Docker Go SDK 常见问题:TLS证书校验失败需配置CA或跳过;镜像名须显式补全registry前缀;ContainerStart后需轮询inspect确认running状态;ExecStart输出需实时读取,exit code需单独inspect获取。

docker.Client 初始化失败:x509: certificate signed by unknown authority
用 docker.NewClientWithOpts 连本地 Docker Daemon 时,常见这个错误——本质是 Go 客户端默认校验 TLS 证书,而 dockerd 默认用自签名证书,且没配可信 CA。
- 开发环境快速绕过:传
docker.WithTLSClientConfig指向空 cert/key/CA 文件,或更直接地用docker.WithHTTPClient自定义不校验证书的http.Client - 生产环境必须配对:把
/var/lib/docker/swarm/certificates/ca.crt(或你生成的 CA)内容读出,传给docker.WithTLSClientConfig - 别硬编码
unix:///var/run/docker.sock:用docker.WithHost+ 环境变量DOCKER_HOST,方便切本地/远程
ContainerCreate 返回 "No such image" 却明明 docker images 能看到
不是镜像真不存在,而是 SDK 默认只查本地 registry,且对镜像名解析比 CLI 更严格——nginx:alpine 和 docker.io/library/nginx:alpine 在 SDK 里算两个不同名字。
- 显式补全 registry 前缀:用
docker.io/library/nginx:alpine替代nginx:alpine,尤其在私有 registry 场景下 - 拉取动作要单独做:调
cli.ImagePull并读取响应流,不能依赖ContainerCreate自动拉 -
ImagePull的io.ReadCloser必须 close,否则连接泄漏,后续请求可能卡住
ContainerStart 后立即 exec.Run 报 “container is not running”
ContainerStart 是异步触发容器启动,但不等它真正进入 running 状态就返回。此时 exec.Create 会失败,因为容器进程还没起来。
- 加轮询检测:用
cli.ContainerInspect查State.Status,循环直到等于"running",最多等 5 秒 - 别用
time.Sleep(1 * time.Second)硬等:容器冷启动可能超 2 秒,尤其挂了 volume 或用了 init container - inspect 返回的
State.Pid为 0 时,说明还没真正 fork 出主进程,比看Status更准
ExecStart 执行命令后 stdout 读不到输出
常见于用 exec.Config{AttachStdout: true} 创建后,直接 io.ReadAll(resp.Stdout) 却返回空——因为 SDK 的 resp 是个未缓冲的 io.ReadCloser,且容器进程可能已退出,连接提前关闭。
立即学习“go语言免费学习笔记(深入)”;
- 必须用
io.Copy或带 buffer 的bufio.Reader边读边处理,不能等 exec 结束再读 - 如果命令执行快(如
ls /),考虑加exec.Config{Tty: true}防止输出被行缓冲截断 - 注意
ExecStart的resp不包含 exit code,得靠cli.ContainerExecInspect轮询查Running和ExitCode
SDK 对容器生命周期的“状态可见性”比 CLI 弱很多,所有涉及状态流转的操作——创建、启动、执行、停止——都不能假设上一步完成就立刻可操作,得主动 inspect 或轮询。这点容易被忽略,尤其从 shell 脚本迁移过来的人。


















