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

时间:2016-07-29 09:46:43

标签: 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

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

2 个答案:

答案 0 :(得分:28)

Dockerfile best practices build cache部分详细解释了构建缓存过程。

  
      
  • 从缓存中已有的基本映像开始,将下一条指令与从中导出的所有子映像进行比较   基本图像,以查看其中一个是否使用完全相同的构建   指令。如果不是,则缓存无效。

  •   
  • 在大多数情况下,只需将Dockerfile中的指令与其中一个子图像进行比较即可。但是,确定   说明需要更多的检查和解释。

  •   
  • 对于ADDCOPY指令,将检查图像中文件的内容,并为每个文件计算校验和。   文件的最后修改时间和最后访问时间不是   在这些校验和中考虑。在缓存查找期间,校验和   与现有图像中的校验和进行比较。如果有什么   已更改文件,如内容和元数据,然后   缓存无效。

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

  •   
     

缓存无效后,所有后续Dockerfile命令   将生成新图像,不会使用缓存。

您将遇到操作系统程序包,NPM程序包或Git仓库更新为较新版本(例如~2.3中的package.json个semver)但作为Dockerfile或{{ 1}}没有更新,docker将继续使用缓存。

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

答案 1 :(得分:5)

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

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

如果您的lib没有变化,这些步骤将从构建缓存中提供。