在Dockerfile中的单次运行指令中指定多个UNIX命令的目的

在Dockerfile中的单次运行指令中指定多个UNIX命令的目的,docker,dockerfile,Docker,Dockerfile,我注意到,许多DockerFile试图通过在一条运行指令中使用几个UNIX命令来最小化指令数。那有什么原因吗 下面两个Dockerfiles之间的结果是否有任何差异 Dockerfile1 Dockerfile2 粗略地说,Docker映像包含一些元数据&一个层数组,运行的容器通过添加一个读写容器层构建在这些层上,底层映像中的层在此时是只读的 根据配置的驱动程序,这些层可以以不同的方式存储在磁盘中。例如,从Docker官方文档中拍摄的以下图像说明了在这些不同层中更改的文件在使用时的考虑方式:

我注意到,许多DockerFile试图通过在一条运行指令中使用几个UNIX命令来最小化指令数。那有什么原因吗

下面两个Dockerfiles之间的结果是否有任何差异

Dockerfile1

Dockerfile2


粗略地说,Docker映像包含一些元数据&一个层数组,运行的容器通过添加一个读写容器层构建在这些层上,底层映像中的层在此时是只读的

根据配置的驱动程序,这些层可以以不同的方式存储在磁盘中。例如,从Docker官方文档中拍摄的以下图像说明了在这些不同层中更改的文件在使用时的考虑方式:

接下来,Dockerfile说明运行、复制和添加创建层,Docker网站上提到的最佳实践特别建议将连续运行命令合并到单个运行命令中,以减少层数,从而减小最终图像的大小:

[…]尽量减少Dockerfile中单独运行命令的数量,从而减少图像中的层数。您可以通过将多个命令合并到一个运行行中,并使用shell的机制将它们组合在一起来实现这一点。[……]

另见:

此外,在你的例子中:

RUN apt-get update -y -q
RUN apt-get install -y nginx

如果你做docker构建-t你的图像名称。在此docker文件上,然后在一段时间后编辑docker文件,在nginx之外添加另一个包,然后再次执行docker build-t您的映像名。由于docker缓存机制,apt get update-y-q不会再次执行,因此apt缓存将被废弃。因此,这是合并两个RUN命令的另一个好处。

除了节省空间外,还涉及正确性

将您的第一个dockerfile视为使用apt的类似debian的系统时的一个常见错误:

如果两个或多个映像遵循此模式,缓存命中可能会由于缓存的元数据而导致映像无法构建

比如说,我在几周前建立了一个类似的图像 现在我今天要建立这个形象。在运行apt get update行之前,缓存一直存在 docker构建将重用该缓存层,因为dockerfile和基本映像在运行apt get update之前是相同的 当RUN-apt-get-install行运行时,它将使用缓存的apt元数据,该元数据现在已过期数周,可能会出错
在上一段中,您的意思是组合多个运行命令可以确保不使用缓存吗?组合运行命令会使缓存失效-你能给我一个关于这个的参考文档吗请注意:我的意思是,给定Docker缓存的规则,一个单独的层运行apt get update-y-q将始终从Docker缓存中重用,因此保留一个包管理器缓存的旧版本。因此,组合多个运行命令可确保在重新运行apt get update命令后,apt get install命令中包列表的更改将执行此命令。如果包列表未更改,则该层将被重新使用。正当我认为RUN只查看命令字符串,而不查看文件内部。是的,在这种情况下该层将被重新使用。我找到的最好的参考是:除了ADD和COPY命令之外,缓存检查不会查看容器中的文件来确定缓存匹配。[…]在这种情况下,仅使用命令字符串本身来查找匹配项。这取决于您如何添加文件-containing-list-of-package.txt:如果您从生成上下文中添加此文件是由于以前的复制行,则任何文件更改都将触发复制行以及所有后续行(包括RUN)的重建;如果您使用命令(如curl-o containing-list-of-package.txt https://…)创建此文件,则可能会忽略文件的远程更改。为什么说在运行apt get update行之前存在缓存。缓存不也包括第二次运行命令吗?不!至少,不总是这样。docker中的缓存为每层
FROM ubuntu 
MAINTAINER demousr@example.com 

RUN apt-get update && apt-get install –y nginx 
CMD ["echo", "Image created"] 
RUN apt-get update -y -q
RUN apt-get install -y nginx
FROM ubuntu 
MAINTAINER demousr@example.com 

RUN apt-get update 
RUN apt-get install –y nginx 
CMD ["echo", "Image created"]