为什么COPY指令在我的Docker构建中导致缓存未命中

时间:2018-04-20 02:24:00

标签: docker haskell travis-ci haskell-stack

我的项目的docker文件中的copy instruction似乎会导致cache miss,即使自上次将图像推送到docker hub以来所复制的文件都没有更改。这会导致所有后续层错过缓存,这使得构建所需的时间比应该的长得多。我还注意到,属于每个层的哈希值似乎与我在本地计算机上'page_item'时的哈希值不同。这可能是因为docker版本不匹配?这里发生了什么?我该如何诊断?

3 个答案:

答案 0 :(得分:2)

使用docker history --no-trunc $image检查正在构建的不同图像的图层。在复制步骤中,您将看到正在复制的文件的“file:abc”哈希值:

IMAGE                                                                     CREATED             CREATED BY                                                                                                        SIZE                COMMENT
sha256:202cb043f70a2565ea40629e891642e1e24be7b52e29116a6520736f47183904   9 minutes ago       /bin/sh -c #(nop) COPY file:d523f0d1cac93e44179baf9c36a7a4feff221b604224e26900075ddb02812448 in /test/test.txt    12B

如果您正在构建的两个图像之间的哈希值不同,那么这将使构建缓存无效并导致未命中。请记住,文件的元数据也可能导致缓存未命中,尤其是文件权限。如果您仍然遇到问题,请更新问题以包含来自不同版本的docker history --no-trunc ...输出。

答案 1 :(得分:1)

您如何完全确定在上下文中是否修改了任何文件? 在docker将上下文发送到引擎的那一刻,你有一个.dockerignore file包含你想要忽略的所有文件/目录吗?

有很多文件可以修改,你不知道。例如,如果您在上述上下文中有.git文件夹并且您创建了git commit,则现在您的缓存将失效。

请务必忽略.dockerignore文件中不需要的文件。

答案 2 :(得分:1)

如果文件的内容确实没有更改,权限中的差异可能导致缓存失效。

  

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

https://docs.docker.com/develop/develop-images/#leverage-build-cache