相同docker-compose配置的两个GitLab Runner运行表现不一致问题排查
问题根因
该问题核心是两台GitLab Runner的Docker执行模式不一致,导致docker-compose的目录挂载逻辑出现错位:
- 运行正常的独立Runner配置了绑定宿主机Docker套接字(/var/run/docker.sock挂载到Runner执行容器),CI任务中执行的docker命令直接调用宿主机Docker daemon,docker-compose.yml中配置的
./:/var/www/html会直接映射到CI作业当前的代码目录,因此可以正常读取到composer.json文件。 - 和GitLab同机的故障Runner使用了配置中声明的
docker:dind服务,CI任务执行的docker命令实际调用dind服务内置的独立Docker daemon,此时./:/var/www/html挂载的是dind服务容器内的当前目录,而dind容器内并未拉取项目代码,因此挂载到php容器内的/var/www/html目录为空,触发找不到composer.json的报错。
你可以通过checks任务的两个ls输出验证该问题:CI作业中直接执行ls -la可以正常显示composer.json,但是通过docker-compose run --entrypoint="ls -la" php执行的ls结果为空。
解决方案
提供三种可落地的修复方案,推荐优先选择第一种:
方案1:调整镜像构建逻辑,内置项目代码(最稳定)
修改项目的Dockerfile,添加代码复制步骤:
# 在原有构建步骤基础上增加 COPY . /var/www/html RUN chown -R www-data:www-data /var/www/html
该方案下构建出来的PHP镜像已经包含完整项目代码,后续测试、检查阶段不需要依赖挂载本地目录,直接注释掉docker-compose.yml中php服务的volumes配置即可,适配所有Runner执行环境,也避免了挂载带来的权限、目录错位问题。
方案2:统一两台Runner的执行模式
修改故障Runner的配置,和正常Runner对齐使用宿主机Docker daemon:
- 登录故障Runner所在服务器,编辑
/etc/gitlab-runner/config.toml - 在对应Runner的
[runners.docker]段添加配置:
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
- 删除
.gitlab-ci.yml中所有任务下的services: - docker:dind配置
修改后两台Runner执行逻辑完全一致,不会出现差异化报错。
方案3:适配dind模式的目录挂载
如果必须保留dind模式和目录挂载配置,可在测试、检查任务的script开头增加代码同步步骤,把CI作业中的代码同步到dind容器对应的挂载路径,该方案复杂度较高,不推荐优先使用。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

