为什么&&而不是一个新的运行
在Dockerfile
我看到了大多数使用这种语法的人
RUN apt-get -y update \ && apt-get install -y libicu-dev
在这一个
RUN apt-get -y update RUN apt-get install -y libicu-dev
对于我来说,第一个只有一行(层)caching,而第二个caching(我错了吗?),一旦命令不成功就停下来。
除此之外,我没有发现第一个更具可读性。
那么我们为什么要使用第一个语法呢?
这是docker图像层的优化。 我也推荐阅读编写Dockerfiles的最佳实践
DockerCon欧盟2017也有趣的演示 。
层次越less,图像越好。
因此,使用&&组合命令将创build一个单一的图层。
有两个RUN将创build两个层。
Dockerfile中的每个命令都会创build另一个图像层 。
组合命令是一种最终减less总体层数的方法。
请参阅https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/#images-and-layers
这一行:
RUN apt-get -y update \ && apt-get install -y libicu-dev
将创build一个单一的docker层和这些行 :
RUN apt-get -y update RUN apt-get install -y libicu-dev
将创build两个不同的层。
这就是为什么当你需要在Docker机器上安装某些东西的时候(例如:通过APT),你往往把所有东西都放在一个单独的行中(又称为层)
正如其他答案已经说过的,每个命令都会生成一个图层,通常希望每个图像的图层数量最less。
每一层只是一个与它之前的层的差异。 这些图层堆叠在一起。 当你创build一个新的容器时,你在底层上添加一个新的可写层。
这意味着,除非你打算“挤压”你的图像(这意味着在构build过程中使用了--squash
选项), --squash
最终会产生一个图像消耗空间。
例
# Dockerfile FROM ubuntu RUN apt-get update RUN apt-get install -y --no-install-recommends dnsutils RUN echo $( dig somewhere.nowhere ) RUN apt-get remove --purge dnsutils RUN rm -rf /var/lib/apt/lists/* COPY magicalScript.sh / CMD /magicalScript.sh
在这种情况下,您将只包含开销的图层:
- 1的caching来自
apt-get update
- 1与
dnsutils
安装, - 1包含去除
dnsutils
- 1包含删除caching
问题是,所有这些层都保留在那里,而且完全没有理由占用空间。
为什么squash
并不总是一个好的解决scheme? 因为这些图层也代表caching。 当你需要执行大量的构build时,它非常有用,而且你需要它们尽可能快。
通常在OS上将新软件包的安装相关的操作分组是很好的做法:
# Dockerfile FROM ubuntu RUN useradd docker \ && mkdir /home/docker \ && chown docker:docker /home/docker \ && addgroup docker staff RUN apt-get update \ && apt-get install -y --no-install-recommends ed less locales vim-tiny wget ca-certificates fonts-texgyre \ && rm -rf /var/lib/apt/lists/* RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen \ && locale-gen en_US.utf8 \ && /usr/sbin/update-locale LANG=en_US.UTF-8 CMD ["mySpecialCommand"]
根据图像和图层文件
每一层只是一个与它之前的层的差异
所以例如2层创build不同的文件不会使用更多的磁盘空间。 特别是因为Docker 17.05 允许多阶段构build 。 但是,如果第二个文件完全从第一个文件修改,它仍然可以使用更多的空间。
按照Khapov Igor的评论,我在最佳实践文档中发现了原始问题的真实答案:
在
RUN
语句中单独使用apt-get update
会导致caching问题,并且随后的apt-get install
指令会失败。
实际上更多的是关于以前的命令的层依赖关系,结果可以像apt-get update
一样随着时间的推移而发展。
这就是为什么他们说:
在同一个
RUN
语句中总是将RUN apt-get update
和apt-get install
结合起来
- 未定义的方法`source_url'为#<Chef :: Cookbook :: Metadata:0x000000006f1378>
- jenkins声明式pipe道 – 如何显示加特林结果?
- docker群与弹性群集
- docker-compose副本主机名
- 使用consuldynamic地将IP和端口导出到另一个Docker容器
- Docker for Windows和Symfony 4中的NGINX 502错误网关错误
- .NET核心getstringasync在Docker中不起作用
- 将容器化的.NET Core MVC / WebAPI应用程序连接到本地安装的Postgres
- 来自守护程序的错误响应:ibmblockchain / fabric-peer的manifest:最新未find