为啥 docker build 中的 COPY 未检测到更新
Posted
技术标签:
【中文标题】为啥 docker build 中的 COPY 未检测到更新【英文标题】:Why is COPY in docker build not detecting updates为什么 docker build 中的 COPY 未检测到更新 【发布时间】:2017-08-21 17:43:27 【问题描述】:我在节点应用程序上运行构建,然后使用工件构建 docker 映像。将我的源移动到适当位置的 COPY 命令没有检测到构建后对源文件的更改;它只是使用缓存。
Step 9/12 : COPY server /home/nodejs/app/server
---> Using cache
---> bee2f9334952
我是在 COPY 上做错了什么,还是有办法不缓存特定步骤?
【问题讨论】:
【参考方案1】:我在Docker documentation:
对于
ADD
和COPY
指令,检查图像中文件的内容并为每个文件计算校验和。这些校验和中不考虑文件的最后修改时间和最后访问时间。在缓存查找期间,将校验和与现有图像中的校验和进行比较。如果文件中有任何更改,例如内容和元数据,则缓存无效。
所以,据我所知,缓存应该是无效的。您可以使用--no-cache
命令行选项来确保。如果您使用--no-cache
得到正确的行为,而没有它的行为不正确,那么您就会发现一个错误并应该报告它。
【讨论】:
谢谢,很高兴知道它是如何工作的。我假设修改时间戳记了。【参考方案2】:这很有趣。我发现COPY
是工作,只是看起来不是。
我正在重建映像并重新启动容器,但容器仍在使用旧映像。我不得不删除我的容器,然后当我启动它们时,它们使用了新创建的映像,我可以看到我的更改。
Here is another thread 处理这个更准确的诊断(在我的情况下)。
【讨论】:
非常感谢这篇文章!我也遇到了同样的问题,没有注意到容器的图像 id 与我刚刚构建的最新图像的 id 不同。【参考方案3】:您可以尝试使用 ADD。它将使副本的缓存无效。不好的一面是它也会使缓存在它之后的其他命令失效。如果您的 ADD 位于最后一步,它应该不会对构建过程产生太大影响。
注意:如果 Dockerfile 的内容已更改,则第一个遇到的 ADD 指令将使 Dockerfile 中的所有后续指令的缓存无效。这包括使 RUN 指令的缓存无效。有关更多信息,请参阅 Dockerfile 最佳实践指南。 https://docs.docker.com/engine/reference/builder/#add
【讨论】:
这也是很好的信息。 这同样适用于 COPY:“如果对我来说,问题在于我对 Docker 构建输出的解释。我没有意识到不仅缓存了层的最后一个版本,而且还缓存了所有以前的版本。
我正在通过来回更改单个文件来测试缓存失效。第一次修改后,缓存失效OK,但是改回来后,图层是从缓存中取出来的,好像失效逻辑不正常。
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
【讨论】:
【参考方案5】:有同样的问题。在考虑了@Nick Brady 的帖子(感谢您的建议!)之后,这是我当前的更新程序,似乎运行良好:
svn update --non-interactive --no-auth-cache --username UUU --password PPP
docker build . -f deploy/Dockerfile -t myimage
docker stop mycontainer
docker rm mycontainer
docker run --name=mycontainer -p 80:3100 -d --restart=always \
--env-file=deploy/.env.production myimage
这里的魔力不是简单地重新启动容器 (docker restart mycontainer
),因为这实际上会停止并再次运行从先前版本的 myimage
实例化的旧容器。停止并销毁旧容器并运行新容器会导致从新建的myimage
实例化一个新容器。
【讨论】:
【参考方案6】:从 Docker 的角度来看,这就像任何其他命令一样。
Docker 看到 这一行 没有改变,所以它缓存了它。
同样,如果你的 Dockerfile 中有 curl 命令,Docker 不会获取 URL 只是为了在它发生更改时进行更改。它检查命令是否改变,而不是结果。
【讨论】:
以上是关于为啥 docker build 中的 COPY 未检测到更新的主要内容,如果未能解决你的问题,请参考以下文章
42-Docker-Docker命令详解-docker build
为啥 COPY package*.json ./ 在 COPY 之前。 .?
为啥 docker-compose build 没有给我这样的文件或目录错误消息
为啥未设置 DBUS_SESSION_BUS_ADDRESS 时 g_file_copy 返回 Operation not supported