构建缓存失效

在构建镜像时,Docker 会逐步执行 Dockerfile 中的指令,并按照指定顺序执行每个指令。对于每个指令,构建器会检查是否可以从构建缓存中重用该指令。

通用规则

构建缓存失效的基本规则如下:

  • 构建器首先检查基础镜像是否已缓存。然后,每个后续指令都与缓存层进行比较。如果没有缓存层与该指令完全匹配,则缓存失效。

  • 在大多数情况下,将 Dockerfile 指令与相应的缓存层进行比较就足够了。但是,有些指令需要额外的检查和说明。

  • 对于 ADDCOPY 指令,以及带有绑定挂载的 RUN 指令(RUN --mount=type=bind),构建器会根据文件元数据计算缓存校验和,以确定缓存是否有效。在缓存查找期间,如果涉及的任何文件的文件元数据已更改,则缓存会失效。

    在计算缓存校验和时,不考虑文件的修改时间(mtime)。如果仅复制文件的 mtime 发生变化,则缓存不会失效。

  • 除了 ADDCOPY 命令外,缓存检查不查看容器中的文件来确定缓存匹配。例如,在处理 RUN apt-get -y update 命令时,不会检查容器中更新的文件来确定是否存在缓存命中。在这种情况下,仅使用命令字符串本身来查找匹配项。

一旦缓存失效,所有后续的 Dockerfile 命令都将生成新的镜像,并且不再使用缓存。

如果您的构建包含多个层,并且您希望确保构建缓存可重用,请尽可能将指令从不经常更改的顺序排列到更经常更改的顺序。

RUN 指令

RUN 指令的缓存不会在构建之间自动失效。假设您的 Dockerfile 中有一个安装 curl 的步骤:

FROM alpine:3.21 AS install
RUN apk add curl

这并不意味着您的镜像中的 curl 版本始终是最新的。一周后重新构建镜像仍将获得与以前相同的软件包。要强制重新执行 RUN 指令,您可以:

  • 确保它之前的一个层已更改
  • 在构建之前使用 docker builder prune 清除构建缓存
  • 使用 --no-cache--no-cache-filter 选项

--no-cache-filter 选项允许您指定要使其缓存失效的特定构建阶段。

$ docker build --no-cache-filter install .

构建机密

构建秘密的内容不属于构建缓存。更改秘密的值不会导致缓存失效。

如果您想在更改秘密值后强制缓存失效,您可以传递一个带有任意值的构建参数,当更改秘密时,您也更改该参数。构建参数确实会导致缓存失效。

FROM alpine
ARG CACHEBUST
RUN --mount=type=secret,id=TOKEN,env=TOKEN \
    some-command ...
$ TOKEN="tkn_pat123456" docker build --secret id=TOKEN --build-arg CACHEBUST=1 .

秘密的属性(例如 ID 和挂载路径)确实参与缓存校验和,如果更改,将导致缓存失效。

© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.