自托管GitLab Runner Dind环境下如何缓存Docker Compose镜像
针对GitLab CI+Dind+Docker Compose的镜像缓存方案
以下是几个适配你场景的可行方案,按推荐程度排序:
方案1:利用自托管Runner绑定宿主机Docker存储目录(最直接)
因为你用的是自托管GitLab Runner,可以直接将宿主机的Docker镜像存储目录挂载到Dind服务容器中,让Dind复用宿主机已拉取的镜像,避免每次流水线重新拉取。
操作步骤:
- 修改GitLab Runner的
config.toml配置文件,在对应runner的[[runners]]块中添加挂载卷:
[[runners]] name = "your-runner-name" url = "https://your-gitlab-instance/" token = "your-runner-token" executor = "docker" [runners.docker] tls_verify = false image = "docker:20.10.16" privileged = true disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = [ "/var/lib/docker:/var/lib/docker", # 关键:挂载宿主机Docker存储目录到Dind容器 "/cache" ] shm_size = 0
- 重启GitLab Runner服务使配置生效:
sudo gitlab-runner restart
- 流水线配置无需大幅修改,可提前拉取镜像确保缓存命中:
test: image: docker:20.10.16 stage: docker_test variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 services: - docker:20.10.16-dind script: - echo "script starts" - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY # 尝试拉取目标镜像,不存在则忽略 - docker pull $CI_REGISTRY/your/project/image:tag || true - docker compose -f docker-compose-cicd.yml up -d
注意:该方案依赖宿主机Docker存储,多Runner节点场景需要每个节点维护独立缓存,适合单节点自托管环境。
方案2:使用GitLab容器注册表作为远程缓存(跨节点通用)
将镜像缓存推送到GitLab私有注册表,流水线运行时优先拉取缓存镜像,避免重复从源仓库拉取,所有Runner节点均可共享缓存。
流水线配置示例:
test: image: docker:20.10.16 stage: docker_test variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 # 用分支名区分不同分支的缓存 CACHE_IMAGE_TAG: $CI_COMMIT_REF_SLUG-cache services: - docker:20.10.16-dind script: - echo "script starts" - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY # 尝试拉取缓存镜像,不存在则忽略 - docker pull $CI_REGISTRY/your/project/image:$CACHE_IMAGE_TAG || true # 将缓存镜像标记为业务使用的标签,让docker-compose直接复用 - docker tag $CI_REGISTRY/your/project/image:$CACHE_IMAGE_TAG $CI_REGISTRY/your/project/image:prod || true # 启动服务 - docker compose -f docker-compose-cicd.yml up -d # 可选:将当前运行的镜像重新标记为缓存镜像并推送,更新缓存 - docker tag $CI_REGISTRY/your/project/image:prod $CI_REGISTRY/your/project/image:$CACHE_IMAGE_TAG - docker push $CI_REGISTRY/your/project/image:$CACHE_IMAGE_TAG
方案3:使用带Buildx的Dind镜像支持Compose缓存
如果坚持想用Docker Compose的cache_from/cache_to功能,可以替换为包含Buildx的Dind镜像,解决环境缺失问题。
流水线配置示例:
test: image: docker:20.10.16 stage: docker_test variables: DOCKER_HOST: tcp://docker:2375 DOCKER_TLS_CERTDIR: "" DOCKER_DRIVER: overlay2 CACHE_DIR: build-cache services: # 使用自定义的带buildx的dind镜像 - name: your-registry/docker-dind-buildx:20.10.16 command: ["--experimental"] cache: key: ${CI_COMMIT_REF_SLUG} paths: - ${CACHE_DIR}/ script: - echo "script starts" - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY # 初始化buildx - docker buildx create --use # 构建镜像时启用本地缓存 - docker compose -f docker-compose-cicd.yml build --cache-from "type=local,dest=./${CACHE_DIR}" --cache-to "type=local,dest=./${CACHE_DIR}" - docker compose -f docker-compose-cicd.yml up -d
自定义带Buildx的Dind镜像示例Dockerfile:
FROM docker:20.10.16-dind RUN apk add --no-cache curl RUN curl -L "https://github.com/docker/buildx/releases/download/v0.10.5/buildx-v0.10.5.linux-amd64" > /usr/lib/docker/cli-plugins/docker-buildx RUN chmod +x /usr/lib/docker/cli-plugins/docker-buildx
构建后推送到你的私有仓库,即可在流水线中使用。
内容的提问来源于stack exchange,提问作者til
相关产品推荐
相关产品推荐

