构建缓存失效
构建镜像时,Docker 将逐步执行 Dockerfile 中的指令,并按照指定的顺序执行每个指令。对于每条指令,Docker 都会检查是否可以重用构建缓存中的指令。
一般规则
构建缓存失效的基本规则如下:
从已经在缓存中的父图像开始,下一条指令将与从该基本图像派生的所有子图像进行比较,以查看其中一个是否是使用完全相同的指令构建的。如果不是,则缓存失效。
在大多数情况下,只需将 Dockerfile 中的指令与子映像之一进行比较就足够了。然而,某些指令需要更多的检查和解释。
对于
ADD
和COPY
指令,修改时间和大小文件元数据用于判断缓存是否有效。在缓存查找期间,如果所涉及的任何文件的文件元数据发生更改,缓存就会失效。除了
ADD
和COPY
命令之外,缓存检查不会查看容器中的文件来确定缓存匹配。例如,在处理RUN apt-get -y update
命令时,不会检查容器中更新的文件以确定是否存在缓存命中。在这种情况下,仅使用命令字符串本身来查找匹配项。
一旦缓存失效,所有后续的 Dockerfile 命令都会生成新的镜像,并且缓存不会被使用。
如果您的构建包含多个层,并且您希望确保构建缓存可重用,请尽可能将指令从不太频繁更改的顺序排列到更频繁更改的顺序。
运行指令
指令缓存RUN
不会在构建之间自动失效。假设您的 Dockerfile 中有一个要安装的步骤curl
:
FROM alpine:3.19 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=foo \
TOKEN=$(cat /run/secrets/foo) ...
$ TOKEN=verysecret docker build --secret id=foo,env=TOKEN --build-arg CACHEBUST=1 .
ID 和挂载路径等机密属性确实参与缓存校验和,如果发生更改,则会导致缓存失效。