Docker RUN命令:何时分组命令,何时不?

 泉州多棱汽车销售服务有限公司 发布于 2022-12-20 15:01

我已经看到了RUN在a 中使用命令的两种不同方法Dockerfile,我将其命名为v1和v2.

V1

每行一个命令

FROM ubuntu/latest
ENV DEBIAN_FRONTEND noninteractive

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

每行多个命令

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

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

NB如果这个问题被认为过于模糊或对意见持开放态度,我会向社区的意愿屈服; 但是,我在这里发布它是因为我希望有很好的情况来分组命令,而不是好的情况 - 我想知道它们是什么.

1 个回答
  • 要回答这个问题,首先必须了解"提交"的概念,以及Docker的缓存.最后,我提供了一个经验法则供您使用.

    提交

    这是一个例子:

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

    运行时docker build .,docker会执行以下操作:

      它从ubuntu/latest图像中启动一个容器.

      touch /commit1在容器中运行第一个command(),并创建一个新图像.

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

      它在第二touch /commit2个容器中运行第二个command(),并创建一个新图像.

    您需要了解的是,如果您将命令分组到一个RUN语句中,那么它们将在同一个容器中执行,并且将对应于单个提交.

    相反,如果在单个RUN语句中断开命令,它们将不会在同一容器中运行,以后的命令将重用先前命令创建的映像.

    高速缓存

    运行时docker build .,docker会重用先前创建的图像.换句话说,如果您编辑上述Dockerfile以包含RUN touch /commit3在最后,并运行a docker build .,那么Doc​​ker将重用#4中创建的映像.

    这很重要,因为当你RUN apt-get update在Dockerfile中包含它时,不能保证它会在几秒钟之前运行RUN apt-get install php5.

    如你所知,提交RUN apt-get update可能是在一个月前创建的.APT缓存不再是最新的,但Docker仍在重用该提交.

    经验法则

    通常更容易在一个RUN命令中对所有内容进行分组,并在您希望开始利用缓存时开始分解(例如,加快构建过程).

    执行此操作时,请确保不要分隔必须在彼此的特定时间间隔内运行的命令(例如,更新和升级).

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

    结论

    在您的示例中,v2是正确的,并且v1是错误的(因为它对缓存起反作用apt-get update).

    2022-12-20 15:04 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有