为什么Docker构建版本中的COPY不检测更新

edqdpe6u  于 2023-03-29  发布在  Docker
关注(0)|答案(8)|浏览(150)

我在一个节点应用程序上运行一个构建,然后使用工件构建一个docker镜像。它只是使用该高速缓存。
Step 9/12 : COPY server /home/nodejs/app/server ---> Using cache ---> bee2f9334952
是我在COPY上做错了什么,还是有办法不缓存特定的步骤?

pn9klfpd

pn9klfpd1#

我在Docker文档中找到了这个:
对于ADDCOPY指令,文件的内容检查映像中的文件,并为每个文件计算校验和。文件的最后修改和最后访问时间在这些校验和中不考虑。该高速缓存查找期间,将校验和与现有映像中的校验和进行比较。如果文件中有任何更改,则(s),诸如内容和元数据,该高速缓存无效。
因此,据我所知该高速缓存应该被无效。您可以使用--no-cache命令行选项来确保。如果您在使用--no-cache时获得正确的行为,而在没有它的情况下获得错误的行为,那么您将发现一个bug并报告它。

hmmo2u0o

hmmo2u0o2#

这很有趣。我发现COPY正在工作,它只是 * 看起来 * 它不是。
我正在重建映像并重新启动容器,但容器仍在使用旧映像。我必须删除容器,然后当我启动它们时,它们使用创建的新映像,我可以看到我的更改。
Here is another thread,处理这个更准确的诊断(在我的情况下)。

5anewei6

5anewei63#

对我来说,问题在于我对Docker构建输出的解释。我没有意识到不仅缓存了层的最后一个版本,而且还缓存了所有以前的版本。
我是通过来回更改单个文件来测试缓存失效的。第一次更改后该高速缓存失效OK,但更改回来后,图层从缓存中取出,似乎失效逻辑无法正常工作。
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache

fnatzsnv

fnatzsnv4#

这可能是一个bug,但很难复制。在Jenkins构建中,当我使用单个DockerfileCOPY命令将新文件复制到现有文件夹时,就会发生这种情况。为了使缓存失效正确工作(并避免像--no-cache那样重建早期层),有必要在主机 *(Jenkins外部)上运行docker build --tag <REPO>/<IMAGE> . *。

1sbrub3j

1sbrub3j5#

你可以尝试使用ADD代替。它会使副本该高速缓存无效。坏的一面是,它也会使它之后的其他命令的缓存无效。如果你的ADD在最后几步,它应该不会对构建过程产生太大影响。
注意:如果Dockerfile的内容已更改,第一个遇到的ADD指令将使Dockerfile中所有后续指令该高速缓存无效。这包括使RUN指令的缓存无效。有关详细信息,请参阅Dockerfile最佳实践指南。https://docs.docker.com/engine/reference/builder/#add

wribegjk

wribegjk6#

也有同样的问题。在考虑@Nick布雷迪的帖子后(谢谢你的建议!),以下是我目前的更新程序,似乎工作正常:

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示例化的新容器。

inb24sb2

inb24sb27#

对我来说,从COPY更改为ADD是成功的,现在当添加的文件更改时,图像是从这一行构建的。

cbjzeqam

cbjzeqam8#

从Docker的Angular 来看,这就像任何其他命令一样。
Docker看到这一行没有改变,所以它缓存了它。
类似地,如果你的Dockerfile中有curl命令,Docker不会仅仅为了改变URL而获取它。它会检查命令是否改变,而不是它的结果。

相关问题