Dockerfile中的多个运行条目与只有一个运行条目有什么区别?

Dockerfile中的多个运行条目与只有一个运行条目有什么区别?,docker,dockerfile,Docker,Dockerfile,Dockerfile中的多个运行条目之间有什么区别,如: FROM php:5.6-apache RUN docker-php-ext-install mysqli RUN apt update RUN apt install git -y -q 只有一次跑步记录 FROM php:5.6-apache RUN docker-php-ext-install mysqli && apt update && apt install git -y -q OBS。

Dockerfile中的多个运行条目之间有什么区别,如:

FROM php:5.6-apache
RUN docker-php-ext-install mysqli 
RUN apt update 
RUN apt install git -y -q
只有一次跑步记录

FROM php:5.6-apache
RUN docker-php-ext-install mysqli && apt update && apt install git -y -q

OBS。我不是问哪一个更好。我想知道这两种方法之间的所有区别。

每个
RUN
命令都会创建一层文件系统更改,这些更改是由运行该命令的临时容器生成的。(它有效地运行
docker运行
,然后将
docker diff
的结果打包到文件系统层。)

这些层有几个关键细节需要注意:

  • 它们是不变的。一旦你创建了它们,你就不会改变它们。您必须生成/重新创建一个新层,以更新图像
  • 它们可以在多个映像和运行的容器之间重用。您可以这样做,因为它是不变性的
  • 您不会从父层删除文件,但可以在以后的层中注册删除文件。这是后一层中的元数据更改,而不是对父层的修改
  • 层在docker的构建缓存中重用。如果两个不同的图像,甚至是重建的同一图像,在同一父层上执行相同的命令,docker将重用已创建的层
  • 这些层被合并到容器内的最终文件系统中
这两种方法之间的主要区别是构建缓存和删除文件。如果将源代码tgz的下载、tgz的提取、二进制编译以及tgz和源文件夹的删除拆分为多行
RUN
,那么当您通过网络发送映像并将其存储在磁盘上时,即使在最后一个容器中看不到源代码,也会在层中包含所有源代码。您的图像将显著增大


当缓存过多时,缓存也可能是一件坏事。如果您拆分了
apt update
apt install
,然后在几个月后将新软件包添加到第二个运行行,docker将重新使用
apt update
的几个月缓存,并尝试安装几个月前的软件包,可能不再可用,并且您的映像可能无法生成。许多人在安装debian软件包后还运行
rm-rf/var/lib/apt/lists/*
。如果您在单独的步骤中执行此操作,您实际上不会从以前的层中删除文件,因此您的图像不会收缩。

Dockerfile的
RUN
部分有我认为的答案。每个
RUN
命令都会创建一个新的“层”。有关这方面的一些“最佳实践”,请同时检查。可能重复: