如何在GitLab CI流水线中正确检测Docker Compose部署状态
GitLab CI部署Docker容器的状态检测方案
配置文件展示
docker-compose.yml
version: '3.9' services: MY_DOCKER_SERVICE_NAME: build: . ports: - '${WEB_SERVER_PORT}:${WEB_SERVER_PORT}' environment: - PORT=${WEB_SERVER_PORT} - MONGODB_URL=${MONGODB_URL} volumes: mongo-data:
.gitlab-ci.yml(简化版)
image: node:18-alpine stages: - prepare - lint - build - deploy # Removed unrelavent parts build_app: stage: build script: - docker compose build --no-cache deploy_app: stage: deploy script: - docker compose up
遇到的问题
- 使用
docker compose up:部署成功后流水线持续运行,无法自动结束 - 使用
docker compose up -d:流水线在容器就绪前提前结束,失败部署也会被标记为成功 - 使用
docker compose up --exit-code-from=MY_DOCKER_SERVICE_NAME:能正确识别失败场景,但成功后流水线仍卡住 - 无法同时使用
-d与--exit-code-from参数
可行解决方案
方案一:日志匹配+状态校验
通过跟踪应用启动日志确认服务就绪,同时校验容器运行状态,脚本如下:
# 后台启动所有服务 docker compose up -d # 跟踪目标服务日志,直到出现启动成功标识,超时设为5分钟 timeout 300s docker compose logs -f MY_DOCKER_SERVICE_NAME | grep -m 1 "Server is running on port ${WEB_SERVER_PORT}" # 检查日志匹配结果,未匹配到则终止流水线 if [ $? -ne 0 ]; then echo "服务启动超时或未成功启动" docker compose down exit 1 fi # 检查容器退出码,异常则终止流水线 CONTAINER_EXIT_CODE=$(docker inspect MY_DOCKER_SERVICE_NAME --format='{{.State.ExitCode}}') if [ $CONTAINER_EXIT_CODE -ne 0 ]; then echo "服务启动失败,退出码:$CONTAINER_EXIT_CODE" docker compose down exit $CONTAINER_EXIT_CODE fi
注:需将
"Server is running on port ${WEB_SERVER_PORT}"替换为你应用启动成功时输出的日志内容,超时时间可根据实际调整。
方案二:Docker健康检查+等待就绪
先给服务添加健康检查规则,再通过docker compose wait等待服务就绪:
- 修改docker-compose.yml,添加健康检查:
version: '3.9' services: MY_DOCKER_SERVICE_NAME: build: . ports: - '${WEB_SERVER_PORT}:${WEB_SERVER_PORT}' environment: - PORT=${WEB_SERVER_PORT} - MONGODB_URL=${MONGODB_URL} healthcheck: test: ["CMD", "curl", "-f", "http://localhost:${WEB_SERVER_PORT}/health"] # 替换为你的健康检查接口 interval: 5s timeout: 5s retries: 10 start_period: 10s volumes: mongo-data:
- 更新GitLab CI部署脚本:
# 后台启动服务 docker compose up -d # 等待服务进入健康状态,超时300秒 timeout 300s docker compose wait MY_DOCKER_SERVICE_NAME # 检查等待结果,超时则终止流水线 if [ $? -ne 0 ]; then echo "服务未在规定时间内进入健康状态" docker compose logs MY_DOCKER_SERVICE_NAME docker compose down exit 1 fi # 二次校验容器运行状态 CONTAINER_STATUS=$(docker inspect MY_DOCKER_SERVICE_NAME --format='{{.State.Status}}') if [ "$CONTAINER_STATUS" != "running" ]; then echo "服务运行状态异常:$CONTAINER_STATUS" docker compose logs MY_DOCKER_SERVICE_NAME docker compose down exit 1 fi
注:健康检查的
test命令需适配你的应用,比如Node.js应用可编写专属健康检查接口或脚本。
预期效果
- 应用启动失败(如触发
process.exit(1))时,流水线会正确标记为失败 - 应用启动成功后,流水线自动结束,容器保持后台运行
- 启动超时或未进入健康状态时,流水线同样标记为失败
内容的提问来源于stack exchange,提问作者anileates
相关产品推荐
相关产品推荐

