You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker-compose --exit-code-from被忽略,CI环境中init容器完成后关闭网络

解决CI流水线中Docker Compose init容器退出后关闭网络且忽略--exit-code-from的问题

我之前在CI环境里踩过类似的Docker Compose坑,结合你的场景,给你几个实用的排查和解决方向:

1. 修正Docker Compose启动命令的参数组合

本地环境和CI环境的Docker Compose默认行为有差异,当你用docker-compose up启动包含一次性init容器的栈时,CI环境可能会因为init容器退出而直接终止整个服务栈,忽略--exit-code-from参数。你需要调整参数,确保init退出后其他容器继续运行,同时指定从目标容器(比如test)获取退出码:

docker-compose up --no-stop-on-exit --exit-code-from test
  • --no-stop-on-exit:阻止Docker Compose在任意容器退出时停止所有其他容器,保证test等服务能正常执行
  • --exit-code-from test:让命令最终返回test容器的退出码,符合CI流水线的结果判断需求

2. 检查并升级CI环境的Docker Compose版本

不同版本的Docker Compose对--exit-code-from和容器退出逻辑的支持有差异,尤其是旧版本(v1.x)可能存在参数兼容问题。建议在CI脚本开头先确认版本:

docker-compose --version

如果版本低于v2.x,建议在CI环境中升级到最新稳定版,比如通过官方脚本安装:

curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

3. 优化Docker Compose配置文件的依赖逻辑

docker-compose.yml中明确init容器的一次性属性,并通过依赖条件确保其他容器在init完成后再启动,避免因依赖关系不明确导致的异常终止:

services:
  init:
    image: your-init-image:latest
    restart: "no"  # 明确设置为不重启,避免CI环境默认配置干扰
    # 其他init相关配置(比如挂载卷、环境变量等)

  db:
    image: your-db-image:latest
    depends_on:
      init:
        condition: service_completed_successfully  # 等待init成功完成后启动
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  test:
    image: your-test-image:latest
    depends_on:
      init:
        condition: service_completed_successfully
      db:
        condition: service_healthy  # 等待数据库健康检查通过后再运行测试

这种配置下,init容器完成预配置退出后,其他服务会按依赖顺序启动,不会被Docker Compose强制终止。

4. 改用分步执行的CI脚本(更可控)

如果上述方法仍有问题,可以放弃用docker-compose up一次性启动所有容器,改用分步执行的方式,完全掌控每个阶段的容器状态:

# 1. 后台启动所有容器(包括init、db、web等)
docker-compose up -d

# 2. 等待init容器完成并退出(确保预配置完成)
docker-compose wait init

# 3. 运行测试容器,并捕获其退出码
docker-compose run --rm test
TEST_EXIT_CODE=$?

# 4. 清理所有容器和网络
docker-compose down

# 5. 将测试容器的退出码返回给CI流水线,决定构建结果
exit $TEST_EXIT_CODE

这种方式完全避开了docker-compose up的默认终止逻辑,每一步都可控,在复杂CI环境中更可靠。


内容的提问来源于stack exchange,提问作者Mark Estrada

火山引擎 最新活动