{{< details >}}

  • Tier: 基础版, 专业版, 旗舰版
  • Offering: JihuLab.com, 私有化部署

{{< /details >}}

使用 Docker-in-Docker 时,Docker 每次创建构建都会下载镜像的所有层。较新的 Docker 版本(Docker 1.13 及之后)可以在 docker build 步骤中使用预先存在的镜像作为缓存。这显著加快了构建过程。

在 Docker 27.0.1 及之后版本中,默认的 docker 构建驱动程序仅在启用 containerd 镜像存储时支持缓存后端。

要在 Docker 27.0.1 及之后版本中使用 Docker 缓存,请执行以下操作之一:

  • 在 Docker 守护进程配置中启用 containerd 镜像存储。
  • 选择不同的构建驱动程序。

Docker 缓存如何工作

运行 docker build 时,Dockerfile 中的每个命令都会创建一个层。这些层作为缓存保留,如果没有更改,可以重用。一个层的更改会导致所有后续层的重新创建。

要指定一个标记的镜像作为 docker build 命令的缓存源,请使用 --cache-from 参数。可以通过使用多个 --cache-from 参数指定多个镜像作为缓存源。

Docker 内联缓存示例

此示例 .gitlab-ci.yml 文件展示了如何使用默认 docker build 命令的 inline 缓存后端进行 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://gitlab.cn/docs/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 部分:

  1. 第一个命令尝试从注册表中拉取镜像,以便它可以作为 docker build 命令的缓存。任何与 --cache-from 参数一起使用的镜像必须在可以用作缓存源之前拉取(使用 docker pull)。
  2. 第二个命令使用拉取的镜像作为缓存(如果可用,参见 --cache-from $CI_REGISTRY_IMAGE:latest 参数)来构建 Docker 镜像,并对其进行标记。--build-arg BUILDKIT_INLINE_CACHE=1 告诉 Docker 使用内联缓存,该缓存将构建缓存嵌入到镜像本身中。
  3. 最后两个命令将标记的 Docker 镜像推送到容器注册表,以便它们也可以作为后续构建的缓存。

Docker 注册表缓存示例

您可以将 Docker 构建直接缓存到注册表中的专用缓存镜像。

此示例 .gitlab-ci.yml 文件展示了如何使用 docker buildx build 命令和 registry 缓存后端进行 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://gitlab.cn/docs/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

  1. 创建并配置支持 registry 缓存后端的 docker-container BuildKit 驱动程序。
  2. 使用以下命令构建并推送 Docker 镜像:

    • 使用 --cache-from type=registry,ref=$CI_REGISTRY_IMAGE/cache-image 的专用缓存镜像。
    • 使用 --cache-to type=registry,ref=$CI_REGISTRY_IMAGE/cache-image,mode=max 进行缓存更新,其中 max 模式缓存中间层。