如何用 docker compose up --exit-code-from 把服务容器退出码传递给调用方?
【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose
docker compose up在默认行为下会把执行错误统一收敛为退出码1,被SIGINT/SIGTERM中断时为0,调用方(CI 脚本、编排系统、上层 shell 逻辑)无法据此区分到底是哪个业务服务失败、以及失败的具体原因。--exit-code-from SERVICE选项解决的就是这个问题:让up命令把指定服务容器的退出码原样返回给调用方,命令本身的退出码就等于该容器进程实际exit时使用的码值。
准备条件
需要一个 Compose 文件,其中至少包含一个会自行退出的目标服务。仓库中的 e2e 测试 fixture TestUpExitCodeFrom/compose.yaml 给出了一份可直接照搬的示例结构:一个长驻服务safe(sleep infinity,永不退出)和一个会失败的一次性任务服务failure(exit 42):
services: safe: image: 'alpine' init: true command: ['/bin/sh', '-c', 'sleep infinity'] # never exiting failure: image: 'alpine' init: true command: ['/bin/sh', '-c', 'sleep 1 ; echo "exiting with error" ; exit 42']把示例中exit 42换成你的真实作业命令即可,服务名、镜像和命令都属于需要按实际情况替换的值。
执行:指定服务并检查命令退出码
在 Compose 文件所在目录执行:
$ docker compose up --exit-code-from=failure failure说明:
--exit-code-from的参数是 Compose 文件中的服务名(string类型),指定后up会返回该服务容器的退出码。- 该选项隐含
--abort-on-container-exit:任一容器退出即停止全部容器,因此不能与-d/--detach搭配(见 docs/reference/compose_up.md 的选项表)。 - 末尾位置参数
failure用来限定只启动该服务;不传位置参数时启动整个项目。 --exit-code-from会隐含--abort-on-container-exit,按 cmd/compose/up.go 中的参数校验,以下组合会被直接拒绝:--detach(-d)与--abort-on-container-exit不兼容;--wait与--abort-on-container-exit、--attach、--attach-dependencies不兼容;--abort-on-container-failure与--abort-on-container-exit不能同时使用。
结果验证
命令退出后,用 shell 的$?读取退出码:
$ docker compose up --exit-code-from=failure failure $ echo $? 42判断标准以仓库 e2e 测试 TestUpExitCodeFrom 为准:该测试执行up --exit-code-from=failure failure后断言命令退出码为42,即与failure服务中exit 42的值一致。上文的42是文档测试中的示例值,你的场景中它应等于目标容器实际的退出码。
另一种需要留意的情况:当被监听服务是长驻容器、而中止是由其他容器退出触发的,该长驻容器会被中止流程停止,其观察到的退出码是信号停止产生的码值。仓库测试 TestUpExitCodeFromContainerKilled 中,up --exit-code-from=test(test为长驻服务)在另一服务退出触发中止后,断言命令退出码为143。
实现机制(便于排查)
如果想确认退出码从哪里来,可以看 pkg/compose/up.go:captureExitCodeFrom监听容器退出事件,取所选服务第一个退出容器的ExitCode记录为会话退出码,最终通过cli.StatusError把该码返回给进程退出状态;stopOnFirstExit则负责在检测到退出后停止整个应用。
与默认退出码的对照
按 docs/reference/compose_up.md 的说明,不带--exit-code-from时:
- 过程遇到错误:
up退出码为1; - 被
SIGINT(Ctrl+C)或SIGTERM中断:容器被停止,退出码为0。
也就是说,默认情况下调用方只能拿到0/1这类粗粒度信号;使用--exit-code-from后,才能把具体服务的退出码(如上面的42)透传给 CI 或上层编排逻辑,用于精确判断哪一步失败。
参考
- 命令选项定义:docs/reference/compose_up.md
- 命令行参数与兼容性校验:cmd/compose/up.go
- 行为测试与断言:pkg/e2e/compose_up_test.go
- 示例 Compose 文件:pkg/e2e/testdata/TestUpExitCodeFrom/compose.yaml
【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考