GitHub Action中如何等待Docker容器健康后再执行单元测试
实现MySQL容器健康后再执行单元测试的可落地方案
前置准备
首先需要确保你的docker-compose.yml中给MySQL服务配置了合法的健康检查规则,没有配置的话补上对应配置,示例配置片段:
mysql: healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s timeout: 3s retries: 12
方案1:使用docker-compose原生等待能力(最推荐,无额外维护成本)
调整两处配置即可:
- 在
myapp服务的定义块中,修改depends_on配置,明确要求MySQL服务健康后再启动应用容器:myapp: depends_on: mysql: condition: service_healthy - 修改CI流程中启动容器的步骤命令,将原有
docker-compose up -d替换为带等待能力的命令:
这个命令会阻塞当前流程,直到所有配置了健康检查的关联服务全部进入docker-compose up -d --waithealthy状态后才会退出,不会额外增加自定义轮询逻辑的维护成本。
方案2:在CI流程中插入自定义健康轮询步骤
如果不想修改原有docker-compose的依赖配置,可以在「show running container」步骤和「run unit test」步骤之间新增一个执行等待逻辑的步骤:
# 轮询检测MySQL容器健康状态,最长等待60秒 MAX_WAIT=60 WAIT_INTERVAL=5 ELAPSED=0 while [ $ELAPSED -lt $MAX_WAIT ]; do CURRENT_STATUS=$(docker inspect --format='{{.State.Health.Status}}' 你的MySQL容器实际名称) if [ "$CURRENT_STATUS" = "healthy" ]; then echo "MySQL容器已达到健康状态,继续执行后续流程" exit 0 fi echo "当前MySQL状态为${CURRENT_STATUS},已等待${ELAPSED}秒" sleep $WAIT_INTERVAL ELAPSED=$((ELAPSED + WAIT_INTERVAL)) done # 超时未就绪则直接判定流程失败 echo "等待MySQL容器健康超时" exit 1
方案3:应用层连接兜底
可以在单元测试初始化数据库连接的代码逻辑中增加重试机制,比如设置最多尝试10次连接,每次间隔2秒,即便MySQL启动存在延迟,也不会因为首次连接失败直接导致测试用例报错。这种方案属于逻辑层兜底,没有容器状态检测的逻辑严谨,适合快速临时调整的场景。
内容的提问来源于stack exchange,提问作者dgggggggğ
相关产品推荐
相关产品推荐

