Dood(Docker-out-of-Docker) 场景下,runner以docker executor方式运行,但是job容器一直访问不到当前代码根目录
·
看起来你是在 DOOD(Docker-out-of-Docker) 场景下用 docker executor 跑 GitLab Runner:job 容器里用 docker 命令去起“兄弟容器”。此时兄弟容器的 volume 路径是由宿主机 Docker 守护进程解释的,而不是 job 容器里的路径——所以你在 job 容器内的“当前代码根目录”($CI_PROJECT_DIR 或 $(pwd))对宿主机来说并不存在,导致“访问不到代码根目录/挂载失败”。
下面给两种可行解法,任选其一。
方案 A:继续 DOOD,但把构建目录绑定为宿主机可见路径(推荐最省改动)
思路:把 Runner 的构建目录($CI_PROJECT_DIR 的上层)在 job 容器和宿主机上保持同一路径,这样当你在 job 容器里做 docker run -v /builds/...:/app 时,宿主机 Docker 也能找到这个路径。
- 修改 Runner 的
config.toml(docker executor 那段):
[[runners]]
[runners.docker]
# 关键:把宿主机 /builds 绑定进 job 容器的 /builds
volumes = [
"/var/run/docker.sock:/var/run/docker.sock",
"/cache",
"/builds:/builds"
]
# 可选:确保构建目录就落在 /builds 下
privileged = false # DOOD 场景一般无需 privileged(按需开启)
disable_cache = false
# 全局设置构建目录(可选但强烈建议)
builds_dir = "/builds"
cache_dir = "/cache"
- 确认 job 内
$CI_PROJECT_DIR形如:
/builds/<group>/<project> 或 /builds/<concurrent-id>/<group>/<project>
- 在
.gitlab-ci.yml中,运行兄弟容器或docker build时用这个绝对路径:
build:
image: docker:25 # 例
services: [] # DOOD 不需要 dind 服务
variables:
DOCKER_HOST: unix:///var/run/docker.sock
script:
- echo "$CI_PROJECT_DIR"
- docker version
# 兄弟容器挂载代码(宿主机会识别 /builds/... 这个真实路径)
- docker run --rm -v "$CI_PROJECT_DIR":/app -w /app alpine:3.20 ls -la
# 或直接构建镜像(以项目根为上下文)
- docker build -t myapp:ci "$CI_PROJECT_DIR"
常见坑
- 不要用
-v $(pwd):/app(这是 job 容器内路径,宿主机不认识);用$CI_PROJECT_DIR的绝对路径。 builds_dir必须和volumes中的映射一致(上例都用/builds)。- 如果你的 Runner 运行在 Docker 里(“docker-in-docker-executor”),也要确保外层宿主机的
/builds目录存在并授予读写。
方案 B:改为 DinD(Docker-in-Docker)模式
思路:不再用宿主机 Docker 守护进程,而是起 docker:dind 服务,job 内的 docker CLI 连接到容器内的守护进程。这时挂载/构建上下文都发生在 job 容器网络里,$CI_PROJECT_DIR 就是本地路径,直接可见。
build:
image: docker:25
services:
- name: docker:25-dind
command: ["--mtu=1450"] # 例:按环境调整
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: "" # 关闭 TLS 简化
script:
- docker version
- docker build -t myapp:ci .
- docker run --rm myapp:ci echo "ok"
常见坑
- DinD 需要给
docker:...-dind服务更高的磁盘与缓存;镜像缓存不会和宿主机共享。 - 网络或镜像拉取慢时注意启用 registry mirror、合理的 MTU。
快速自检清单
- Runner
config.toml的volumes是否包含/builds:/builds与/var/run/docker.sock:/var/run/docker.sock(走 DOOD 时需要) -
builds_dir是否设置为/builds(或与 volumes 对应的一致路径) - CI 脚本里是否使用 绝对路径
$CI_PROJECT_DIR给docker run -v/docker build - 若改用 DinD:是否设置了
DOCKER_HOST=tcp://docker:2375且起了docker:dind服务
更多推荐

所有评论(0)