首页 > 解决方案 > 在 Dockerfile 中的单个 RUN 指令中指定多个 UNIX 命令的目的

问题描述

我注意到许多人试图通过一条指令中Dockerfiles的多个命令来最小化指令数量。那么有什么理由吗?UNIXRUN

下面的两个 Dockerfile 之间的结果也有什么不同吗?

Dockerfile1

FROM ubuntu 
MAINTAINER demousr@example.com 

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

Dockerfile2

FROM ubuntu 
MAINTAINER demousr@example.com 

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

标签: dockerdockerfile

解决方案


粗略地说,一个 Docker 镜像包含一些元数据和一个层数组,一个正在运行的容器是通过添加一个容器层(读写)在这些层上构建的,底层镜像中的层在那时是只读的.

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

接下来,Dockerfile 的指令RUN、、COPYADD创建层,以及 Docker 网站上提到的最佳实践,特别推荐将连续RUN的命令合并到一个RUN命令中,以减少层数,从而减小最终图像的大小

https://docs.docker.com/develop/dev-best-practices/

RUN[…] 尝试通过最小化Dockerfile中单独命令的数量来减少镜像中的层数。您可以通过将多个命令合并到RUN一行并使用 shell 的机制将它们组合在一起来做到这一点。[…]

另见:https ://docs.docker.com/develop/develop-images/dockerfile_best-practices/

此外,在您的示例中:

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

如果你这样做docker build -t your-image-name .Dockerfile然后Dockerfile过一会儿编辑,添加另一个包nginx,然后再做一次docker build -t your-image-name .,由于Docker缓存机制,apt-get update -y -q不会再次执行,所以APT缓存将被淘汰。所以这是合并这两个RUN命令的另一个好处。


推荐阅读