Docker RUN命令:何时分组命令? [英] Docker RUN Command: When To Group Commands, When Not To?

查看:177
本文介绍了Docker RUN命令:何时分组命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到在 Dockerfile 中使用 RUN 命令的两种截然不同的方法,我将命名为v1和v2。



v1



每行一个命令



$ ub untu ub ub ub dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev dev $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
RUN libcurl4-openssl-dev
...



v2



每行多个命令

  FROM ubuntu / latest 
ENV DEBIAN_FRONTEND非交互式
RUN apt-get update&& \
apt-get -y install \
php5-dev \
libcurl4-openssl-dev
...

这两种方法都有其优点,使用缓存的不同方法是最明显的。另外还有什么其他原因可以使用一种方法?



NB 如果这个问题被认为太模糊,开放意见然而,我在这里发布,因为我希望有一个很好的情况下分组命令,好的情况不是 - 我想知道他们是什么。

解决方案

为了回答这个问题,您必须首先了解提交的概念和Docker的缓存。最后,我提供一个经验法则供您使用。



提交



这是一个例如:

 #Dockerfile 
FROM ubuntu / latest
RUN touch / commit1
RUN touch / commit2

当您运行 docker build。 ,docker执行以下操作:


  1. 它从 ubuntu / latest 启动一个容器

  2. 它在容器中运行第一个命令( touch / commit1 ),并创建一个新映像。

  3. 它重新使用#2中创建的图像启动新的容器。

  4. 它运行第二个命令( touch / commit2 ),并创建一个新的图像。

你需要理解的是,如果你分组命令在单个 RUN 语句中,则它们都将在同一容器中执行,并将对应于单个提交。



相反,如果您在单独的 RUN 语句中中断命令,则它们不会在同一容器中运行,稍后的命令将重用先前命令创建的映像。



缓存



当您运行 docker build。时,docker重新使用先前创建的图像。换句话说,如果您编辑上述的Docker文件,最后包含 RUN touch / commit3 ,并运行一个 docker版本。,那么Doc​​ker会重用在#4中创建的映像。



这很重要,因为当你包含 RUN apt-get update 在您的Docker文件中,那么不能保证这将在运行apt-get install php5 之前运行秒。



对于您所知道的,可以在一个月前创建一个 RUN apt-get update 的提交。 APT缓存不再是最新的,但Docker仍然重用该提交。



Thumb的规则



将所有内容分组到一个 RUN 命令,并且当您想要开始利用缓存(例如加快构建过程)时,开始分解它。



当您这样做时,请确保不要分离必须在相互间隔一段时间内运行的命令(例如更新和升级)。



一个很好的做法是避免您的命令的副作用(即,在安装所需的软件包后清理APT缓存)。



结论



在你的例子中, v2 是正确的, v1 是错误的(因为缓存 apt-get update 是有用的)。


I've seen two distinct methodologies of using the RUN command in a Dockerfile, which I will name v1 and v2.

v1

One command per line

FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update
RUN apt-get -y install php5-dev
RUN libcurl4-openssl-dev
...

v2

Multiple commands per line

FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
    apt-get -y install \
        php5-dev \
        libcurl4-openssl-dev
...

Both methodologies have their advantages, the different approach to using caching being the most obvious. What other reasons are there to use one approach over the other?

N.B. I bow to the community's wishes if this question be considered too vague or open to opinion; however, I post it here because I expect that there are good situations to group commands, and good situations not to - and I want to know what they are.

解决方案

To answer this question, you must first understand the concept of "commits", and Docker's caching. At the end, I'm providing a rule of thumb for you to use.

Commits

Here's an example:

# Dockerfile
FROM ubuntu/latest
RUN touch /commit1
RUN touch /commit2

When you run docker build ., docker does the following:

  1. It launches a container from the ubuntu/latest image.
  2. It runs the first command (touch /commit1) in the container, and creates a new image.
  3. It reuses the image created in #2 to launch a new container.
  4. It runs the second command (touch /commit2) in the second container, and creates a new image.

What you need to understand here is that if you group commands in a single RUN statement, then they will all execute in the same container, and will correspond to a single commit.

Conversely, if you break the commands up in individual RUN statements, they won't run in the same container, later commands will reuse the images created by earlier commands.

Caching

When you run a docker build ., docker reuses the images that were created earlier. In other words, if you edited the aforementioned Dockerfile to include RUN touch /commit3 at the end, and ran a docker build ., then Docker would reuse the image created in #4.

This matters because when you include RUN apt-get update in your Dockerfile, then it isn't guaranteed that this will run seconds before RUN apt-get install php5.

For all you know, the commit with RUN apt-get update could have been created a month ago. The APT cache is no longer up to date, but Docker is still reusing that commit.

Rule of Thumb

It's usually easier to group everything in a single RUN command, and start breaking it up when you want to start taking advantage of caching (e.g. to speedup the build process).

When you do that, just make sure you don't separate commands that must run within a certain time interval of one another (e.g. an update and an upgrade).

A good practice is to avoid side effects from your commands (i.e. to clean the APT cache after you've installed the packages you needed).

Conclusion

In your example, v2 is correct, and v1 is wrong (because it's counterproductive to cache apt-get update).

这篇关于Docker RUN命令:何时分组命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆