在Linux上用GitLab Runner实现Docker-in-Docker(DinD)模式,核心是通过socket挂载或dind服务容器提供隔离Docker环境:前者轻量但共享宿主机daemon,后者需privileged模式且支持buildx多平台编译,配置需在config.toml启用privileged、.gitlab-ci.yml中声明services及TLS参数,并注意安全与清理。

在 Linux 上用 GitLab Runner 实现 Docker-in-Docker(DinD)模式,核心目标是让 CI 作业能在隔离容器中安全、可控地执行 docker build、docker push 或 buildx build --platform 等需要完整 Docker 环境的操作。这不是简单挂个 sock 就完事,而是要兼顾功能、安全与可维护性。
明确 DinD 的两种实现路径
GitLab Runner 本身不内置 Docker Daemon,所以必须通过 executor 层提供运行时支持:
-
Socket 挂载方式(推荐用于常规构建):容器启动时挂载宿主机的
/var/run/docker.sock,所有 docker 命令直通宿主机 Docker 引擎。优点是轻量、启动快、无需特权;缺点是构建镜像会污染宿主机镜像库,且无法真正隔离构建上下文(比如不同 job 同时 build 同名镜像可能冲突)。 -
DinD 服务容器方式(适合多平台/高隔离需求):使用
docker:dind镜像作为 sidecar 容器,为每个 job 提供独立的 Docker Daemon。必须启用privileged: true,且需 TLS 通信或禁用 TLS(仅限内网可信环境)。这是真正“容器里跑容器”的模式,适用于buildx多架构编译、构建过程中需运行容器测试等复杂场景。
配置支持 DinD 的 Docker Executor
关键在于 config.toml 中的 executor 设置和 job 级别声明:
监控一个或多个 GitCode 仓库的 PR,通过 OpenClaw Gateway 自动执行 AI 审查,发布 PR 评论,并发送钉钉和企业微信通知。
- 注册 runner 时选择
docker类型,image 可设为docker:stable-git(含 git 和 docker cli); - 在
config.toml的[[runners.docker]]区块中添加:privileged = true(DinD 必需)disable_cache = false(可选,避免缓存干扰)pull_policy = "if-not-present"(减少拉取延迟) - 若使用 TLS 模式(生产推荐),需挂载证书卷并设置环境变量:
volumes = ["/certs/client:/certs/client:ro", "/cache"]environment = ["DOCKER_HOST=tcp://docker:2376", "DOCKER_TLS_VERIFY=1", "DOCKER_CERT_PATH=/certs/client"]
在 .gitlab-ci.yml 中启用 DinD 服务
不能只靠 runner 全局配置,job 必须显式声明依赖:
- 启用服务容器(TLS 关闭示例):
services:<br> - docker:dind
并设置DOCKER_HOST: tcp://docker:2376和DOCKER_TLS_VERIFY: 0 - 若需 buildx 支持多平台(如 x86_64 构建 arm64 镜像):
在 job 开头运行:docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
然后初始化 builder:docker buildx create --use --name mybuilder
最后用:docker buildx build --platform linux/arm64,linux/amd64 -t $CI_REGISTRY_IMAGE . - 注意:DinD 容器默认无网络访问权限,如需拉取私有 registry 镜像,应在 job 中提前
docker login,或通过before_script注入凭证。
安全与运维要点
DinD 不是银弹,用错反而引入风险:
- 避免长期运行 privileged 容器,建议 job 结束后自动销毁 DinD 实例(默认行为);
- 不要在 DinD 容器内运行不受信代码,因其拥有近乎宿主机 root 权限;
- 定期清理宿主机上的 dangling 镜像和构建缓存,防止磁盘爆满;
- 敏感凭证(如 registry token)务必使用 GitLab CI Variables 加密,禁止硬编码进脚本或镜像;
- 监控 runner 日志中的
Failed to connect to docker daemon或permission denied on /var/run/docker.sock,多数源于挂载路径错误或 SELinux/AppArmor 限制(CentOS/RHEL 系统需加:Z标签)。

















