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

Dan*_*tos 1 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 Code Online (Sandbox Code Playgroud)

只有一个RUN条目?

FROM php:5.6-apache
RUN docker-php-ext-install mysqli && apt update && apt install git -y -q
Run Code Online (Sandbox Code Playgroud)

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

BMi*_*tch 5

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

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

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

这两种方法的主要区别在于构建缓存和删除文件.如果您将源代码tgz的下载,tgz的提取,编译二进制文件以及删除tgz和源文件夹分成多RUN行,那么当您通过网络发送图像并将其存储在磁盘上时,即使您没有在最终容器中看到它,您将拥有图层中的所有源.你的图像会大得多.

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