Dockerfile中的多个RUN条目和一个RUN条目之间有什么区别?

时间:2018-09-17 12:51:58

标签: docker dockerfile

Dockerfile中的多个RUN条目之间有什么区别?

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

只有一个RUN条目吗?

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

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

1 个答案:

答案 0 :(得分:5)

每个RUN命令都会创建一个文件系统更改层,该文件系统更改由开始运行该命令的临时容器生成。 (它实际上是在运行docker run,然后将docker diff的结果打包到文件系统层中。)

这些层有一些关键细节要注意:

  • 它们是一成不变的。创建它们后,您将不会对其进行更改。您将必须生成/重新创建一个新图层,以更新您的图像。
  • 它们可在多个映像和正在运行的容器之间重用。您可以这样做,因为它不可更改。
  • 您不从父层删除文件,但是可以注册在更高层删除文件。这是后一层的元数据更改,而不是对父层的修改。
  • 层在docker的构建缓存中被重用。如果两个不同的图像,或者甚至是相同的图像正在重建,请在同一父层的顶部执行相同的命令,则docker将重用已创建的层。
  • 这些层被合并到您在容器内看到的最终文件系统中。

两种方法之间的主要区别是构建缓存和删除文件。如果将源代码tgz的下载,tgz的提取,编译二进制文件以及tgz和源文件夹的删除分成多个RUN行,则在通过网络发送映像时,将其存储在磁盘上,即使在最终容器中看不到它,您也将在图层中拥有所有源。您的图片会大很多。

当您缓存太多时,缓存也可能是一件坏事。如果您将apt updateapt install分开,然后在几个月后添加新软件包以安装到第二个运行行,则docker将重用几个月前的apt update缓存并尝试安装软件包已有数月的历史,可能不再可用,并且您的映像可能无法构建。许多人在安装debian软件包后也运行rm -rf /var/lib/apt/lists/*。而且,如果您在单独的步骤中执行此操作,则实际上不会删除先前图层中的文件,因此图像不会缩小。