Docker如何知道在构build过程中何时使用caching?

我很惊讶Docker的图层caching效果如何,但是我也想知道它是如何确定它是否可以使用caching图层。

让我们以这些构build步骤为例:

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的caching层,但为npm install创build一个新层?

构buildcaching过程在Dockerfile最佳实践构buildcaching部分中进行了相当详细的解释。

  • 从已经在caching中的基本映像开始,将下一条指令与从该基本映像导出的所有子映像进行比较,以查看是否使用完全相同的指令构build了其中的一条。 否则,caching失效。

  • 在大多数情况下,只需将Dockerfile的指令与其中一个子映像进行比较就足够了。 但是,某些说明需要多一点的检查和解释。

  • 对于ADDCOPY指令,将检查映像中文件的内容,并为每个文件计算校验和。 这些校验和中不考虑文件的最后修改时间和最后访问时间。 在caching查找过程中,将校验和与现有映像中的校验和进行比较。 如果文件中有任何内容已经改变,如内容和元数据,则caching失效。

  • ADDCOPY命令之外,caching检查不会查看容器中的文件以确定caching匹配。 例如,处理RUN apt-get -y update命令时,将不会检查容器中RUN apt-get -y update的文件,以确定是否存在caching命中。 在这种情况下,只有命令string本身将用于查找匹配。

一旦caching失效,所有后续的Dockerfile命令将生成新的映像,caching将不会被使用。

你会遇到操作系统软件包,NPM软件包或者Git仓库更新到更新的版本(比如说package.json ~2.3版本),但是由于你的Dockerfile或者package.json没有更新, Dockerfile会继续使用caching。

可以编程方式生成一个Dockerfile ,通过修改特定智能检查上的行(例如,从repo中检索最新的git分支shasum来在clone指令中使用)来破坏caching。 您也可以使用--no-cache=true定期运行构build来执行更新。

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

这也是docker build期间首先COPY package-manager(vendor / 3rd-party)信息文件的原因。 之后,运行程序包pipe理器安装,然后添加应用程序的其余部分,即src

如果你没有改变你的库,这些步骤是从构buildcaching中提供的。