使用 Docker 层缓存加速 Docker-in-Docker 构建
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
在使用 Docker-in-Docker 时,Docker 每次创建构建都会下载镜像的所有层。
Docker 的较新版本(Docker 1.13 及以上)可以在 docker build 步骤中使用现有镜像作为缓存。
这能显著加快构建过程。
在 Docker 27.0.1 及以上版本中,默认的 docker 构建驱动仅在启用 containerd 镜像存储时才支持缓存后端。
要在 Docker 27.0.1 及以上版本中使用 Docker 缓存,请执行以下操作之一:
- 在 Docker 守护进程配置中启用
containerd镜像存储。 - 选择其他构建驱动。
更多信息,请参阅 Cache storage backends。
Docker 缓存工作原理
运行 docker build 时,Dockerfile 中的每个命令都会创建一个层。
这些层会被保留为缓存,如果没有变更就可以重用。某一层的变更会导致其后所有层的重新创建。
要指定用作 docker build 命令缓存源的有标签镜像,请使用 --cache-from 参数。
可以通过多个 --cache-from 参数指定多个镜像作为缓存源。
Docker 内联缓存示例
此示例 .gitlab-ci.yml 文件展示了如何使用 inline 缓存后端和默认的 docker build 命令来使用 Docker 缓存。
default:
image: docker:27.4.1
services:
- docker:27.4.1-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
build:
stage: build
script:
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest在 build 任务的 script 部分:
- 第一个命令尝试从镜像仓库拉取镜像,以便用作
docker build命令的缓存。 任何与--cache-from参数一起使用的镜像都必须先通过docker pull拉取,才能用作缓存源。 - 第二个命令使用拉取的镜像作为缓存(参见
--cache-from $CI_REGISTRY_IMAGE:latest参数)构建 Docker 镜像(如果可用),并为其打上标签。--build-arg BUILDKIT_INLINE_CACHE=1告诉 Docker 使用 内联缓存,将构建缓存嵌入到镜像本身中。 - 最后两个命令将标记的 Docker 镜像推送到容器注册表,以便它们也可以用于后续构建的缓存。
Docker 注册表缓存示例
您可以将 Docker 构建直接缓存到注册表中的专用缓存镜像中。
此示例 .gitlab-ci.yml 文件展示了如何使用 docker buildx build 命令和 registry 缓存后端来使用 Docker 缓存。
有关更高级的缓存选项,请参阅 Cache storage backends。
default:
image: docker:27.4.1
services:
- docker:27.4.1-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
build:
stage: build
script:
- docker context create my-builder
- docker buildx create my-builder --driver docker-container --use
- docker buildx build --push -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--cache-to type=registry,ref=$CI_REGISTRY_IMAGE/cache-image,mode=max
--cache-from type=registry,ref=$CI_REGISTRY_IMAGE/cache-image .build 任务的 script:
-
创建并配置支持
registry缓存后端的docker-containerBuildKit 驱动。 -
构建并推送 Docker 镜像,使用:
--cache-from type=registry,ref=$CI_REGISTRY_IMAGE/cache-image指定专用缓存镜像。--cache-to type=registry,ref=$CI_REGISTRY_IMAGE/cache-image,mode=max进行缓存更新,其中max模式会缓存中间层。