缓存存储后端

为确保快速构建,BuildKit 会将其构建结果自动缓存到其内部缓存中。此外,BuildKit 还支持将构建缓存导出到外部位置,以便在未来的构建中导入。

外部缓存对于 CI/CD 构建环境几乎是必不可少的。这类环境通常在运行之间几乎没有持久性,但保持镜像构建的运行时尽可能低仍然很重要。

默认的 docker 驱动程序支持 inlinelocalregistrygha 缓存后端,但前提是你已启用containerd 镜像存储。其他缓存后端要求你选择不同的驱动程序

警告

如果在构建流程中使用密钥或凭据,请确保使用专用的 --secret 选项对其进行操作。手动使用 COPYARG 管理密钥可能会导致凭据泄露。

后端

Buildx 支持以下缓存存储后端

  • inline:将构建缓存嵌入到镜像中。

    内联缓存会推送到与主要输出结果相同的位置。这仅适用于 image 导出器

  • registry:将构建缓存嵌入到单独的镜像中,并推送到与主要输出分开的专用位置。

  • local:将构建缓存写入文件系统上的本地目录。

  • gha:将构建缓存上传到 GitHub Actions 缓存(测试版)。

  • s3:将构建缓存上传到 AWS S3 存储桶(未发布)。

  • azblob:将构建缓存上传到 Azure Blob 存储(未发布)。

命令语法

要使用任何缓存后端,首先需要在构建时使用 --cache-to 选项指定它,以便将缓存导出到你选择的存储后端。然后,使用 --cache-from 选项从存储后端导入缓存到当前构建中。与本地 BuildKit 缓存(始终启用)不同,所有缓存存储后端都必须显式导出和显式导入。

使用 registry 后端的 buildx 命令示例,使用导入和导出缓存

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>[,parameters...] \
  --cache-from type=registry,ref=<registry>/<cache-image>[,parameters...] .

警告

一般来说,每个缓存都会写入某个位置。同一个位置不能写入两次,否则会覆盖之前缓存的数据。如果要维护多个范围缓存(例如,每个 Git 分支一个缓存),则确保为导出的缓存使用不同的位置。

多缓存

BuildKit 支持多个缓存导出器,允许你将缓存推送到多个目标。你还可以从任意多个远程缓存导入。例如,一个常见的模式是同时使用当前分支和主分支的缓存。以下示例展示了使用 registry 缓存后端从多个位置导入缓存

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>:<branch> \
  --cache-from type=registry,ref=<registry>/<cache-image>:<branch> \
  --cache-from type=registry,ref=<registry>/<cache-image>:main .

配置选项

本节介绍生成缓存导出时可用的一些配置选项。此处描述的选项对于至少两种或更多后端类型是通用的。此外,不同的后端类型也支持特定的参数。有关哪些配置参数适用的更多信息,请参阅每种后端类型的详细页面。

此处描述的通用参数是

缓存模式

生成缓存输出时,--cache-to 参数接受一个 mode 选项,用于定义导出缓存中包含哪些层。所有缓存后端(inline 缓存除外)都支持此选项。

模式可设置为以下两个选项之一:mode=minmode=max。例如,要使用 mode=max 和 registry 后端构建缓存

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,mode=max \
  --cache-from type=registry,ref=<registry>/<cache-image> .

此选项仅在导出缓存时使用 --cache-to 设置。导入缓存时 (--cache-from),相关参数会自动检测。

min 缓存模式(默认)下,仅将导出到最终镜像的层进行缓存,而在 max 缓存模式下,所有层都会缓存,甚至是中间步骤的层。

虽然 min 缓存通常更小(可以加快导入/导出时间并降低存储成本),但 max 缓存更有可能获得更多缓存命中。根据构建的复杂性和位置,你应该尝试这两种参数,以找到最适合你的结果。

缓存压缩

缓存压缩选项与导出器压缩选项相同。localregistry 缓存后端支持此选项。

例如,使用 zstd 压缩压缩 registry 缓存

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,compression=zstd \
  --cache-from type=registry,ref=<registry>/<cache-image> .

OCI 媒体类型

缓存 OCI 选项与导出器 OCI 选项相同。localregistry 缓存后端支持这些选项。

例如,要导出 OCI 媒体类型缓存,请使用 oci-mediatypes 属性

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,oci-mediatypes=true \
  --cache-from type=registry,ref=<registry>/<cache-image> .

此属性仅对 --cache-to 标志有意义。获取缓存时,BuildKit 会自动检测要使用的正确媒体类型。

默认情况下,OCI 媒体类型会为缓存镜像生成一个镜像索引。一些 OCI 注册表,例如 Amazon ECR,不支持镜像索引媒体类型:application/vnd.oci.image.index.v1+json。如果将缓存镜像导出到 ECR 或任何其他不支持镜像索引的注册表,请将 image-manifest 参数设置为 true,以便为缓存镜像生成单个镜像清单,而不是镜像索引

$ docker buildx build --push -t <registry>/<image> \
  --cache-to type=registry,ref=<registry>/<cache-image>,oci-mediatypes=true,image-manifest=true \
  --cache-from type=registry,ref=<registry>/<cache-image> .
页面选项