Docker如何知道何时在构建期间使用缓存,何时不知道?

Hed*_*dge 35 caching docker

我很惊讶Docker的层缓存有多好,但我也想知道它是如何确定它是否可以使用缓存层.

我们以这些构建步骤为例:

Step 4 : RUN npm install -g   node-gyp
 ---> Using cache
 ---> 3fc59f47f6aa
Step 5 : WORKDIR /src
 ---> Using cache
 ---> 5c6956ba5856
Step 6 : COPY package.json .
 ---> d82099966d6a
Removing intermediate container eb7ecb8d3ec7
Step 7 : RUN npm install
 ---> Running in b960cf0fdd0a
Run Code Online (Sandbox Code Playgroud)

例如,它如何知道它可以使用缓存层npm install -g node-gyp但为其创建一个新层npm install

Mat*_*att 36

Dockerfile最佳实践构建缓存部分中详细解释了构建缓存过程.

  • 从已经在高速缓存中的基础图像开始,将下一条指令与从该基础图像导出的所有子图像进行比较,以查看它们中的一个是否使用完全相同的指令构建.如果不是,则缓存无效.

  • 在大多数情况下,简单地比较Dockerfile一个子图像中的指令就足够了.但是,某些说明需要更多的检查和解释.

  • 对于ADDCOPY指令,检查图像中文件的内容,并计算每个文件的校验和.在这些校验和中不考虑文件的最后修改时间和最后访问时间.在高速缓存查找期间,将校验和与现有映像中的校验和进行比较.如果文件中的任何内容(例如内容和元数据)发生了任何更改,则缓存将失效.

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

缓存无效后,所有后续Dockerfile命令都将生成新映像,并且不会使用缓存.

您将遇到操作系统软件包,NPM软件包或Git存储库更新到较新版本(例如~2.3semver package.json)的情况,但是当您Dockerfile或未package.json更新时,docker将继续使用缓存.

Dockerfile通过修改某些更智能的检查上的行(例如,从repo中检索最新的git branch shasum以在clone指令中使用),可以以编程方式生成破坏缓存的内容.您还可以定期运行构建--no-cache=true以强制执行更新.


sch*_*unk 6

这是因为您的package.json文件已被修改,请参见Removing intermediate container

这通常也是COPY在期间首先编辑软件包管理器(供应商/第三方)信息文件的原因docker build。之后,您将运行软件包管理器安装,然后添加其余的应用程序,即src

如果您的库没有任何更改,则从构建缓存执行这些步骤。