最小化Dockerfile中的图层数量

在这个官方docker工具用户指南的build议之一是最小化Dockerfile中的层数。

我认为这是减less图像的总大小,但发现一些关于层的最大限制: 在Dockerfile中的命令数

但是,由于caching而划分单独的命令是非常有帮助的。

例如,有一个像这样的Dockerfile:

# https://hub.docker.com/_/php/ FROM php:5.5.23-fpm RUN /scripts/base.sh \ && /scripts/composer.sh \ && /scripts/mbstring.sh \ && /scripts/bcmath.sh \ && /scripts/mcrypt.sh \ && /scripts/sockets.sh \ && /scripts/zip.sh \ && /scripts/phpredis.sh \ && /scripts/cleanup.sh 

这只是一层,所以一旦build成,它会caching。 但是如果我改变了phpredis的版本,每个步骤都会重新生成。

我可以将它们分成独立的RUN指令吗? 你能告诉我吗?

Dockerfile的“devise”主要取决于你的需求和你想要平衡的东西。 最小化层数被认为是最佳实践,但正如您已经提到的那样,caching通过明确地创build一个新层来工作。 数量有限的链接问题可能会成为Docker文件较大的问题,但这也取决于系统上configuration的存储驱动程序。 你的示例Dockerfile(即使每个脚本都在自己的RUN语句中)也没有达到图层的限制,所以你不必担心。

这就是说,我想你并没有完全理解图层caching如何工作(也许你没有发布完整的Dockerfile?)。 Docker不知道在RUN语句中脚本将产生哪些文件系统更改。 因此,当您使用该确切的Dockerfile重新运行Docker构build时,Docker将不会再运行您的脚本。 你提到的例子是phpredis版本可能会改变,但是Dockerfile并不反映这个variables。 我build议在相关的RUN语句之前声明一些ENVvariables。 例:

 # https://hub.docker.com/_/php/ FROM php:5.5.23-fpm RUN /scripts/base.sh \ && /scripts/composer.sh \ && /scripts/mbstring.sh \ && /scripts/bcmath.sh \ && /scripts/mcrypt.sh \ && /scripts/sockets.sh \ && /scripts/zip.sh \ && /scripts/cleanup.sh ENV PHPREDIS_VERSION=1.2.3 RUN /scripts/phpredis.sh \ && /scripts/cleanup.sh 

phpredis.sh应该使用环境variables。 每次更改ENV ...语句时,Docker将在该步骤后重新运行每个语句,包括您的phpredis.sh脚本。

也许最近宣布的多阶段构build也有助于重新devise让您的图像保持微小的方式,并减less对cleanup.sh脚本的需求。

如果你有第二个RUN包含

/scripts/phpredis.sh \ && /scripts/cleanup.sh

第一个RUN将被caching。

最近的docker版本,如1.13,你有

docker build --squash

看文档

https://docs.docker.com/engine/reference/commandline/build/#options