Dockerfile 中 RUN 和 CMD 的区别

     2023-02-19     233

关键词:

【中文标题】Dockerfile 中 RUN 和 CMD 的区别【英文标题】:Difference between RUN and CMD in a Dockerfile 【发布时间】:2016-09-24 12:25:35 【问题描述】:

我对何时应该使用 CMDRUN 感到困惑。例如,要执行 bash/shell 命令(即ls -la),我将始终使用CMD,或者是否存在使用RUN 的情况?试图了解这两个相似的Dockerfile 指令的最佳实践。

【问题讨论】:

docs.microsoft.com/en-us/virtualization/windowscontainers/… 【参考方案1】:

RUN 是一个镜像构建步骤,RUN 命令之后的容器状态将提交给容器镜像。一个 Dockerfile 可以有许多 RUN 步骤,这些步骤相互叠加以构建映像。

CMD 是启动构建镜像时容器默认执行的命令。一个 Dockerfile 只会使用最终定义的CMD。使用docker run $image $other_command 启动容器时,可以覆盖CMD

ENTRYPOINT也与CMD密切相关,可以修改容器启动镜像的方式。

【讨论】:

你做了所有RUN需要设置你的环境,并且你的(唯一的)CMD启动在你的容器中运行的进程,例如,对于nginx,从github.com/nginxinc/docker-nginx/blob/…中提取你看到@行987654332@ “一个 Dockerfile 只能有一个 CMD”——从技术上讲并不正确,但实际上除了一个之外的所有命令都将被忽略。查看 GingerBeer 的答案。 “一个 Dockerfile 将只使用最终定义的 CMD”?实际上,最终定义的 CMD 将用于启动镜像作为容器,对吧? 是的@paulcheung dockerfile 中的最终命令被写入镜像,并且是容器在启动构建镜像时默认执行的命令。 "一个 Dockerfile 将只使用最终定义的 CMD。" ——我只是浪费了过去的一个小时,因为我没有意识到这一点。如果他们要忽略这些,为什么他们至少不会给你一个警告?【参考方案2】:

RUN - 在我们构建 docker 镜像时触发命令。

CMD - 在我们启动创建的 docker 镜像时触发命令。

【讨论】:

【参考方案3】:

我发现this 的文章对理解它们之间的区别很有帮助:

运行 - RUN 指令允许您安装应用程序和软件包 需要它。它在当前图像之上执行任何命令 并通过提交结果创建一个新层。很多时候你会发现 Dockerfile 中有多个 RUN 指令。

CMD - CMD 指令允许您设置默认命令,该命令将是 仅当您在不指定命令的情况下运行容器时执行。 如果 Docker 容器使用命令运行,则默认命令为 忽略。如果 Dockerfile 有多个 CMD 指令,除了最后一个 CMD 指令被忽略。

【讨论】:

那个链接太棒了!【参考方案4】:

RUN - 安装 Python,你的容器现在已经将 python 烧入了它的镜像 CMD - python hello.py,运行你喜欢的脚本

【讨论】:

CMD - 安装 Python,我的容器现在没有将 python 烧入它的镜像吗? RUN会创建python的镜像层,CMD只会执行命令不创建镜像【参考方案5】:

现有答案涵盖了查看此问题的任何人所需的大部分内容。所以我只会介绍 CMD 和 RUN 的一些小众领域。

CMD:允许重复但很浪费

GingerBeer 提出了一个重要的观点:如果您输入多个 CMD,则不会出现任何错误 - 但这样做很浪费。我想用一个例子来详细说明:

FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"

如果你将它构建到一个镜像中并在这个镜像中运行一个容器,那么正如 GingerBeer 所说,只有最后一个 CMD 会被注意。所以该容器的输出将是:

执行 CMD 2

我的想法是“CMD”正在为正在构建的整个图像设置一个全局变量,因此连续的“CMD”语句只会覆盖之前对该全局变量的任何写入,并在最终图像中那是最后一个写胜利的人。由于 Dockerfile 是按从上到下的顺序执行的,我们知道最底层的 CMD 是获得这个最终“写入”的命令(比喻地说)。

RUN:如果图像被缓存,命令可能不会执行

关于 RUN 需要注意的一个微妙点是,即使存在副作用,它也会被视为纯函数,因此会被缓存。这意味着如果 RUN 有一些不会改变结果图像的副作用,并且该图像已经被缓存,则 RUN 将不会再次执行,因此副作用不会在后续构建中发生。例如,以这个 Dockerfile 为例:

FROM busybox
RUN echo "Just echo while you work"

第一次运行时,你会得到这样的输出,带有不同的字母数字 ID:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

请注意,上面执行了 echo 语句。第二次运行它,它使用缓存,你不会在构建的输出中看到任何回显:

docker build -t example/run-echo .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM busybox
 ---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
 ---> Using cache
 ---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest

【讨论】:

【参考方案6】:

注意:不要将 RUN 与 CMD 混淆。 RUN 实际上运行一个命令并且 提交结果; CMD 在构建时不执行任何操作,但是 指定图像的预期命令。

来自 docker 文件参考

https://docs.docker.com/engine/reference/builder/#cmd

【讨论】:

【参考方案7】:

运行命令: RUN 命令基本上会在我们构建映像时执行默认命令。它还将为下一步提交图像更改。

可以有多个 RUN 命令,以帮助构建新映像。

CMD 命令: CMD 命令只会为新容器设置默认命令。这不会在构建时执行。

如果一个 docker 文件有超过 1 个 CMD 命令,那么除了最后一个之外,所有的命令都会被忽略。因为这个命令不会执行任何东西,只是设置默认命令。

【讨论】:

【参考方案8】:

RUN:可以是多个,用于build过程,例如安装多个库

CMD:只能有 1 个,这是您的执行起点(例如["npm", "start"]["node", "app.js"]

【讨论】:

【参考方案9】:

RUNCMD 上已有足够的答案。我只想在 ENTRYPOINT 上补充几句。 CMD 参数可以被命令行参数覆盖,而 ENTRYPOINT 参数总是被使用。

This article 是一个很好的信息来源。

【讨论】:

那个链接太棒了!

dockerfile中cmd命令和entrypoint命令的说明

...用,也可以单个命令使用。当CMD和ENTRYPOINT都出现在一个DockerFile中时,CMD中设置的信息(EXEC格式的)都以参数的形式提供给ENTRYPOINT命 查看详情

4,dockerfile的基本使用

dockerfile:FROM构建新镜像是基于哪个镜像MAINTAINER镜像维护者姓名或邮箱地址RUN构建镜像时运行的Shell命令COPY拷贝文件或目录到镜像中ENV设置环境变量USER为RUN、CMD和ENTRYPOINT执行命令指定运行用户EXPOSE声明容器运行的服务端口HEALTHCHE... 查看详情

8dockerfile详解

除了init之外,每一个进程都应该是其他进程的子进程(init是内核启动的),当手动启动nginx时,那么这个nginx就以shell子进程存在。当打开一个命令行提示符时,这个就相当于在运行一个shell进程,当在shell命令行中运行一个命令时... 查看详情

CMD Dockerfile 中的转义命令

】CMDDockerfile中的转义命令【英文标题】:EscapingcommandinCMDDockerfile【发布时间】:2021-04-0700:44:24【问题描述】:要执行sbt来执行我使用的特定Main方法:sbt"run-maintickdata.Main"命令sbt"run-maintickdata.Main"在docker中应该如何使用。... 查看详情

dockerfile里指定执行命令用entrypoing和用cmd有何不同?

结论:运行时机不太一样。RUN是在Build时运行的,先于CMD和ENTRYPOINT。Build完成了,RUN也运行完成后,再运行CMD或者ENTRYPOINT。ENTRYPOINT和CMD的不同点在于执行dockerrun时参数传递方式,CMD指定的命令可以被dockerrun传递的命令覆盖,例... 查看详情

使用 docker run 命令将参数传递给 Dockerfile 中的 CMD

】使用dockerrun命令将参数传递给Dockerfile中的CMD【英文标题】:UsedockerruncommandtopassargumentstoCMDinDockerfile【发布时间】:2017-04-1321:05:49【问题描述】:我是Docker新手,我很难根据需要设置docker容器。我有一个nodejs应用程序在启动时... 查看详情

dockerfile中entrypoint和cmd的区别

一、dockerfile中的CMD   1、每个dockerfile中只能有一个CMD如果有多个那么只执行最后一个。   2、CMD相当于启动docker时候后面添加的参数看,举个简单例子:      dockerrun-itd--namewohaoshuaidocker_image(这个是镜像名称)/bin/ba... 查看详情

详解docker——你需要知道的docker进阶知识五

参考技术ADockerfile是一个文本文件,其中包含了构建Docker镜像需要执行的命令序列。使用dockerbuild命令从Dockerfile中读取指令来构建镜像。构建镜像时,该过程的第一件事是将Dockerfile文件所在目录下的所有内容发送给Docker守护进程... 查看详情

dockerfile中cmd和entrypoint的区别

1-联系允许用户指定容器的默认执行的命令2-区别CMD有3种格式,Exec格式是CMD的推荐格式Exec格式:CMD["executable","param1","param2"]CMD["param1","param2"]为ENTRYPOINT提供额外的参数,此时EN 查看详情

dockerfile中cmd和entrypoint的用法

一、ENTRYPOINT指令ENTRYPOINT的两种格式:?ENTRYPOINT["executable","param1","param2"](exec格式,推荐使用此格式)?ENTRYPOINTcommandparam1param2(shell格式)ENTRYPOINT的目的和CMD一样,都是指定容器的启动程序及参数。ENTRYPO 查看详情

dockerdockerfile指令

Dockerfile指令CMDCMD指令用于指定一个容器启动时要运行的命令。这有点儿类似于RUN指令,只是RUN指令是指定镜像被构建时要运行的命令,而CMD是指定容器被启动时要运行的命令。这和使用dockerrun命令启动容器时指定要运行的命令... 查看详情

dockerfile中的cmd与entrypoint(代码片段)

原文:Dockerfile中的CMD与ENTRYPOINTCMD和ENTRYPOINT指令都是用来指定容器启动时运行的命令。单从功能上来看,这两个命令几乎是重复的。单独使用其中的一个就可以实现绝大多数的用例。但是既然doker同时提供了它们,为了在使用中不... 查看详情

docker(dockerfile-node)(代码片段)

...就是lastest。注意后面有一个空格和点。2.Dockfile语法  Dockerfile的基本指令有十三个,分别是:FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD。下面对这些指令的用法一一说明。2.1FROM  用法... 查看详情

dockerfile详解文件指令详解(代码片段)

...概述2.7.2、语法2.8、ENV指令2.8.1、概述2.8.2、语法2.8.3、在Dockerfile中使用变量的方式2.9、RUN指令2.9.1、概述2.9.2、语法2.9.3、语法解释2.10、CMD指令2.10.1、概述2.10.2、语法2.10.3、语法解释2.10.3、注意事项2.11、RUN指令和CMD指令区别2.12、... 查看详情

dockefiile知识点总结和发布自己的镜像

参考技术A1.dockerfile的基本定义2.dockerfile的基本结构3.dockerfile的常用指令FROM:指定基础镜像,必须是第一个命令MAINTAINER:维护者信息RUN:构建镜像时执行的命令ADD:将本地文件添加到容器中COPY功能和ADD类似,区别如下CMD:构建容器这后使... 查看详情

Dockerfile 中的 CMD 和 ENTRYPOINT 有啥区别?

】Dockerfile中的CMD和ENTRYPOINT有啥区别?【英文标题】:WhatisthedifferencebetweenCMDandENTRYPOINTinaDockerfile?Dockerfile中的CMD和ENTRYPOINT有什么区别?【发布时间】:2014-02-2811:21:48【问题描述】:在Dockerfiles中有两个与我相似的命令:CMD和ENTRYPO... 查看详情

dockerfile的常用指令和构建案例(代码片段)

Dockerfile的常用指令和构建案例一、Dockerfile操作常用的指令(1)FROM镜像(2)MAINTAINER名字(3)RUN命令(4)ENTRYPOINT["要运行的程序","参数1","参数2"](5)CMD["要运行的程序","参数1","参数2 查看详情

dockerfile的常用指令和构建案例(代码片段)

Dockerfile的常用指令和构建案例一、Dockerfile操作常用的指令(1)FROM镜像(2)MAINTAINER名字(3)RUN命令(4)ENTRYPOINT["要运行的程序","参数1","参数2"](5)CMD["要运行的程序","参数1","参数2 查看详情