我已经看到了RUN在a 中使用命令的两种不同方法Dockerfile,我将其命名为v1和v2.
每行一个命令
FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get -y install php5-dev
RUN libcurl4-openssl-dev
...
Run Code Online (Sandbox Code Playgroud)
每行多个命令
FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get -y install \
php5-dev \
libcurl4-openssl-dev
...
Run Code Online (Sandbox Code Playgroud)
这两种方法都有其优点,使用缓存的不同方法最为明显.还有什么其他原因可以使用一种方法而不是另一种方法?
NB如果这个问题被认为过于模糊或对意见持开放态度,我会向社区的意愿屈服; 但是,我在这里发布它是因为我希望有很好的情况来分组命令,而不是好的情况 - 我想知道它们是什么.
Tho*_*zco 26
要回答这个问题,首先必须了解"提交"的概念,以及Docker的缓存.最后,我提供了一个经验法则供您使用.
这是一个例子:
# Dockerfile
FROM ubuntu/latest
RUN touch /commit1
RUN touch /commit2
Run Code Online (Sandbox Code Playgroud)
运行时docker build .,docker会执行以下操作:
ubuntu/latest图像中启动一个容器.touch /commit1在容器中运行第一个command(),并创建一个新图像.touch /commit2个容器中运行第二个command(),并创建一个新图像.您需要了解的是,如果您将命令分组到一个RUN语句中,那么它们将在同一个容器中执行,并且将对应于单个提交.
相反,如果在单个RUN语句中断开命令,它们将不会在同一容器中运行,以后的命令将重用先前命令创建的映像.
运行时docker build .,docker会重用先前创建的图像.换句话说,如果您编辑上述Dockerfile以包含RUN touch /commit3在最后,并运行a docker build .,那么Docker将重用#4中创建的映像.
这很重要,因为当你RUN apt-get update在Dockerfile中包含它时,不能保证它会在几秒钟之前运行RUN apt-get install php5.
如你所知,提交RUN apt-get update可能是在一个月前创建的.APT缓存不再是最新的,但Docker仍在重用该提交.
通常更容易在一个RUN命令中对所有内容进行分组,并在您希望开始利用缓存时开始分解(例如,加快构建过程).
执行此操作时,请确保不要分隔必须在彼此的特定时间间隔内运行的命令(例如,更新和升级).
一个好的做法是避免命令的副作用(即在安装所需的软件包后清理APT缓存).
在您的示例中,v2是正确的,并且v1是错误的(因为它对缓存起反作用apt-get update).
| 归档时间: |
|
| 查看次数: |
2785 次 |
| 最近记录: |