构建缓存失效
在构建镜像时,Docker 会逐步执行 Dockerfile 中的指令,并按照指定顺序执行每个指令。对于每个指令,构建器会检查是否可以从构建缓存中重用该指令。
通用规则
构建缓存失效的基本规则如下:
构建器首先检查基础镜像是否已缓存。然后,每个后续指令都与缓存层进行比较。如果没有缓存层与该指令完全匹配,则缓存失效。
在大多数情况下,将 Dockerfile 指令与相应的缓存层进行比较就足够了。但是,有些指令需要额外的检查和说明。
对于
ADD和COPY指令,以及带有绑定挂载的RUN指令(RUN --mount=type=bind),构建器会根据文件元数据计算缓存校验和,以确定缓存是否有效。在缓存查找期间,如果涉及的任何文件的文件元数据已更改,则缓存会失效。在计算缓存校验和时,不考虑文件的修改时间(
mtime)。如果仅复制文件的mtime发生变化,则缓存不会失效。除了
ADD和COPY命令外,缓存检查不查看容器中的文件来确定缓存匹配。例如,在处理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 和挂载路径)确实参与缓存校验和,如果更改,将导致缓存失效。