
Docker 提供了两种官方机制判断 docker exec 中命令是否执行完毕:非分离模式下 WebSocket 自动关闭即表示结束;分离模式下可通过 /exec/{id}/json 接口轮询 Running 字段状态。
docker 提供了两种官方机制判断 `docker exec` 中命令是否执行完毕:非分离模式下 websocket 自动关闭即表示结束;分离模式下可通过 `/exec/{id}/json` 接口轮询 `running` 字段状态。
在使用 Docker REST API 调用 POST /containers/{id}/exec 启动命令(如 Maven 构建)后,准确感知其生命周期结束是实现自动化流程(如 CI/CD 编排、状态同步或资源清理)的关键。Docker 原生支持两种可靠方案,无需额外“黑盒”技巧:
✅ 方案一:非分离模式(推荐用于短时、确定性任务)
设置请求体中的 "Detach": false(默认值),并建立 WebSocket 连接调用 POST /exec/{id}/start。此时:
- Docker 会将命令的 stdout/stderr 流式传输至 WebSocket;
- 一旦命令进程退出(无论成功或失败),WebSocket 连接将自动关闭;
- 客户端监听
onclose事件即可精确判定执行完成,并通过后续GET /exec/{id}/json获取ExitCode。
// exec 创建请求(示例)
{
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Detach": false,
"Tty": false,
"Cmd": ["mvn", "clean", "package", "-DskipTests"]
}⚠️ 注意:若需向 stdin 写入数据(如交互式命令),务必在输入完成后显式关闭 stdin 流(发送 FIN 包),否则容器内 shell 可能持续等待输入而无法退出。
✅ 方案二:分离模式 + 轮询状态(适用于长时或后台任务)
设置 "Detach": true,API 立即返回 exec ID,不建立流式连接。随后定期调用:GET /exec/{id}/json
检查响应中的 Running 字段:
-
true→ 命令仍在运行; -
false→ 已终止,此时ExitCode字段有效(0 表示成功)。
建议轮询间隔 ≥1s,避免高频请求;可结合指数退避策略优化性能。
? 总结与最佳实践
- 优先选用非分离模式:语义清晰、事件驱动、资源释放及时;
- 避免“模拟终端行为”或依赖日志关键词匹配等不可靠方式;
- 若必须分离执行,请确保轮询逻辑具备超时和重试机制;
- 所有 exec 操作均应配套
ExecInspect查询以获取最终退出码,而非仅依赖连接状态。
通过合理运用 Docker 原生 API 的状态机设计,即可构建健壮、可预测的容器内命令编排能力。


















