Docker RUN命令

时间:2016-09-12 01:59:44

标签: docker dockerfile

关于Docker的CMDRUNENTRYPOINT之间article的{{3}}段落后,我感到很困惑。

  

请注意,apt-get updateapt-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在单独的行上所产生的任何影响。

1 个答案:

答案 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所提到的,修复程序是以相同的运行步骤运行更新并安装,这样当安装缓存失效时,更新也会重新运行。