关于Docker的CMD
与RUN
与ENTRYPOINT
之间article的{{3}}段落后,我感到很困惑。
请注意,
apt-get update
和apt-get install
在单个RUN指令中执行。这样做是为了确保安装最新的软件包。如果apt-get install
在单独的RUN指令中,那么它将重用由apt-get update
添加的层,这可能是很久以前创建的。
该段落的代码是:
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
我真的不理解他们将apt-get install
放在同一行上的解释。 apt-get update
不会完成,然后apt-get install...
会在单独的行中继续进行吗?这篇文章听起来好像apt-get install...
看不到apt-get update
在单独的行上所产生的任何影响。
答案 0 :(得分:4)
参考是对层的缓存。无论何时对同一个前一层运行相同的命令,Docker都会尝试为该命令重用缓存层。
因此,如果您在几个月后将另一个包添加到列表中并重新运行docker build
,如果您创建了两个单独的RUN命令,apt-get update
图层将从缓存中重用,并且您' d在图像中有一个3个月的缓存。在第二个RUN上的新apt-get install
命令中安装软件包的尝试将从包中不再存在的任何旧软件包中失败。
通过使它成为单个RUN命令,它是文件系统缓存中的单个层,因此它从现在起重新开始重建几个月的更新,并且您对当前位于软件包存储库中的软件包进行安装。
编辑:似乎这仍然不清楚,这是一个如何出错的示例场景:
使用以下Dockerfile:
FROM debian:latest
RUN apt-get update
RUN apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
当我运行docker built -t my-app:latest .
时,它会输出一个以:
Processing triggers for libc-bin (2.19-18+deb8u4) ...
Processing triggers for systemd (215-17+deb8u4) ...
Processing triggers for ca-certificates (20141019+deb8u1) ...
Updating certificates in /etc/ssl/certs... 174 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for sgml-base (1.26+nmu4) ...
---> 922e466ac74b
Removing intermediate container 227318b98393
Successfully built 922e466ac74b
现在,如果我更改此文件以将解压缩添加到包列表中,并假设它已经过了几个月,那么apt-get update
现在包含陈旧数据:
FROM debian:latest
RUN apt-get update
RUN apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion \
unzip
如果我现在运行它,它将起作用:
Step 1 : FROM debian:latest
---> 1b088884749b
Step 2 : RUN apt-get update
---> Using cache
---> 81ca47119e38
Step 3 : RUN apt-get install -y bzr cvs git mercurial subversion unzip
---> Running in 87cb8380ec90
Reading package lists...
Building dependency tree...
The following extra packages will be installed:
ca-certificates dbus file fontconfig fontconfig-config fonts-dejavu-core
gir1.2-glib-2.0 git-man gnupg-agent gnupg2 hicolor-icon-theme
....
Processing triggers for libc-bin (2.19-18+deb8u4) ...
Processing triggers for systemd (215-17+deb8u4) ...
Processing triggers for ca-certificates (20141019+deb8u1) ...
Updating certificates in /etc/ssl/certs... 174 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
Processing triggers for sgml-base (1.26+nmu4) ...
---> d6d1135481d3
Removing intermediate container 87cb8380ec90
Successfully built d6d1135481d3
但如果您查看上面的输出,apt-get update
会显示:
---> Using cache
这意味着它没有运行更新,它只是重用了之前运行该步骤的旧层。当这只有5分钟时,这没有问题。但是,当它持续数月之后,你会看到错误。
正如Docker所提到的,修复程序是以相同的运行步骤运行更新并安装,这样当安装缓存失效时,更新也会重新运行。