需显式初始化hostconfig和networkingconfig;containerconfig.image必填带tag镜像名;hostconfig.mounts.type须小写;端口映射需exposedports与portbindings配合;containercreate返回id即注册成功,可立即start;日志需设follow=false并用io.copy接收;exit code应通过containerwait获取statuscode。

怎么用 github.com/docker/docker/api/types 创建容器
创建容器不是调用一个函数就完事,得先拼好配置结构体,再传给 Client.ContainerCreate。最常漏的是 HostConfig 和 NetworkingConfig 没显式初始化,导致容器启动后没网络、没挂载卷、甚至直接退出。
-
ContainerConfig.Image必须填镜像名,比如"nginx:alpine";空字符串或只写"nginx"(没 tag)在某些 registry 会拉取失败 -
HostConfig要手动 new:用&container.HostConfig{AutoRemove: true},别用 nil,否则默认值全关,连端口映射都无效 - 挂载卷时,
HostConfig.Mounts里每个Mount的Type必须是"bind"或"volume",小写,写成"Bind"会静默忽略 - 端口映射要两步:先在
ContainerConfig.ExposedPorts声明map[string]struct{}{"80/tcp": {}},再在HostConfig.PortBindings填map[string][]nat.PortBinding{"80/tcp": {{HostPort: "8080"}}}
为什么 Client.ContainerStart 报 “No such container” 却明明刚创建成功
因为 ContainerCreate 返回的 container.ContainerCreateCreatedBody 里只有 ID 字段,不包含状态或是否已注册到 daemon。常见错误是没等创建完成就去 start,或者用了 CreatedBody.Warnings 误以为创建失败而跳过后续操作。
- 检查返回 error 是否为 nil,而不是看
Warnings—— 拉取镜像慢时会有 warning,但创建仍成功 -
ContainerCreate是同步 API,ID 返回即表示已注册,可立刻ContainerStart - 如果 start 失败报 “No such container”,大概率是传了错误的 ID(比如取了
CreatedBody.ID[:12]但 daemon 返回的是完整 64 位 hash,截断后不匹配) - 调试时直接打印
CreatedBody.ID,然后用docker ps -a | grep $ID手动确认是否存在
如何安全地获取容器日志并避免阻塞和乱码
Client.ContainerLogs 默认是流式读取,不设超时或缓冲容易卡死;而且原始日志是带 ANSI 控制符的字节流,直接转 string 可能显示异常字符。
- 必须传
types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Timestamps: true, Follow: false}——Follow: true会让连接一直挂着,不主动 close 就泄露 goroutine - 用
io.Copy+bytes.Buffer接收,别用ReadAll,大日志会 OOM - 日志内容是
[]byte,每行以\r\n或\n结尾,不是 UTF-8 完整字符边界,逐行处理前先做bytes.TrimRight(logLine, "\r\n") - 如果容器输出了中文,确保宿主机 locale 是
en_US.UTF-8或同级,否则 daemon 可能按 latin1 编码返回字节
容器退出后怎么拿到真实 exit code 而不是 -1
Client.ContainerInspect 返回的 types.ContainerJSON 里,State.ExitCode 在容器运行中是 0,退出后才更新。但很多人 inspect 太早,或者没 reload 状态,看到的还是旧值。
立即学习“go语言免费学习笔记(深入)”;
- 必须等容器状态变成
"exited"或"dead"后再 inspect,可用Client.ContainerWait阻塞等待:waitResp, _ := Client.ContainerWait(ctx, id, container.WaitConditionNotRunning) -
ContainerWait返回的chan container.ContainerWaitOKBody,读出后它的StatusCode就是真实 exit code,比 inspect 更准、更及时 - inspect 到的
State.OOMKilled是 bool,和 exit code 无关;State.Error是启动失败原因,不是运行时错误 - exit code 为 137 表示被 OOM killer 杀掉,不是程序主动返回,这时
State.OOMKilled == true










