You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker.Dotnet SDK创建容器后立即退出,求最小可行实现代码

问题:Docker.Dotnet SDK创建容器后直接进入exited状态,求最小可行代码

我用Docker.Dotnet SDK创建容器,所用镜像通过Docker Compose可以正常启动,但调用API创建并启动容器时没有任何警告或错误,容器却直接进入exited状态。现在需要一份通过Docker API(任意SDK或直接调用端点)创建并启动容器的最小可行代码。

我当前的代码如下:

var exposedPorts = new Dictionary<string, EmptyStruct>();
exposedPorts.Add(recorderHttpPort, new EmptyStruct());

var createResponse = await client.Containers.CreateContainerAsync(new CreateContainerParameters()
{
    Image = recorderImage.ID,
    Name = containerName,
    ExposedPorts = exposedPorts,
    HostConfig = new HostConfig()
    {
        DNS = new[] { $"0.0.0.0:{recorderHttpPort}" }
    }
});

解决方法

首先看你代码里的明显问题:HostConfig.DNS配置错误,DNS参数只能填纯IP地址(比如"8.8.8.8"),不能带端口,你写的"0.0.0.0:{recorderHttpPort}"完全不符合DNS配置规则,这可能是容器启动失败的原因之一。

另外,Docker Compose会自动处理很多默认配置(比如容器启动命令、端口映射、环境变量等),但Docker.Dotnet SDK创建容器时需要显式指定这些必要配置,否则容器可能因为没有持续运行的前台进程直接退出。

下面是最小可行的C#代码,包含完整的容器创建+启动流程,覆盖核心必要配置:

using Docker.DotNet;
using Docker.DotNet.Models;
using System.Collections.Generic;

class Program
{
    static async Task Main(string[] args)
    {
        // 初始化Docker客户端(本地Windows环境用npipe,Linux/macOS用unix:///var/run/docker.sock)
        using var client = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine"))
            .CreateClient();

        var imageName = "nginx:alpine"; // 替换成你的镜像名/ID
        var containerName = "test-running-container";
        var containerPort = "80/tcp"; // 镜像暴露的端口,必须带协议
        var hostPort = "8080"; // 宿主机映射的端口

        // 构建容器创建参数
        var createParams = new CreateContainerParameters
        {
            Image = imageName,
            Name = containerName,
            // 若镜像有默认前台启动命令,可留空;否则需显式指定(比如["nginx", "-g", "daemon off;"])
            Cmd = new List<string>(),
            // 声明暴露的端口,和镜像Dockerfile的EXPOSE对应
            ExposedPorts = new Dictionary<string, EmptyStruct>
            {
                { containerPort, new EmptyStruct() }
            },
            HostConfig = new HostConfig
            {
                // 端口映射:宿主机端口 -> 容器端口
                PortBindings = new Dictionary<string, IList<PortBinding>>
                {
                    {
                        containerPort,
                        new List<PortBinding> { new PortBinding { HostPort = hostPort } }
                    }
                },
                // 可选:配置正确的DNS服务器IP
                DNS = new[] { "8.8.8.8", "1.1.1.1" }
            },
            // 可选:添加镜像需要的环境变量
            Env = new List<string> { "APP_ENV=production" }
        };

        // 创建容器
        var createResponse = await client.Containers.CreateContainerAsync(createParams);

        // 启动容器
        await client.Containers.StartContainerAsync(createResponse.ID, new ContainerStartParameters());

        Console.WriteLine($"容器 {createResponse.ID} 已成功启动");
    }
}

关键注意事项:

  • 端口格式:ExposedPorts和PortBindings里的端口必须带协议(比如"80/tcp"),不能只写数字。
  • 前台进程:容器必须有持续运行的前台进程才不会退出。如果你的镜像默认CMD是后台运行,需要改成前台模式(比如Nginx加daemon off;参数)。
  • 配置对齐:对比你的docker-compose.yml,把里面的环境变量、卷挂载、启动命令、网络配置等同步到CreateContainerParameters里,确保和Compose启动的配置一致。
  • 排查退出原因:如果还是出现exited状态,用docker logs <容器ID>查看日志,或docker inspect <容器ID>查看状态详情,这是定位问题最直接的方法。

内容的提问来源于stack exchange,提问作者Reuben Sivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:27:38