Docker文件中RUN和CMD之间的差异

时间:2016-05-26 13:11:20

标签: docker dockerfile

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

9 个答案:

答案 0 :(得分:281)

RUN是一个图像构建步骤,RUN命令之后的容器状态将提交到docker镜像。 Dockerfile可以有许多RUN个步骤,它们相互叠加以构建图像。

CMD是启动构建映像时容器默认执行的命令。 Dockerfile只能有一个CMD。使用CMD启动容器时,可以覆盖docker run $image $other_command

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

答案 1 :(得分:49)

我发现this文章非常有助于理解它们之间的区别:

RUN -     RUN指令允许您安装应用程序和包     需要它。它在当前图像的顶部执行任何命令     并通过提交结果创建一个新图层。通常你会发现     Dockerfile中的多个RUN指令。

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

答案 2 :(得分:49)

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

CMD - 在我们启动创建的泊坞窗图像时触发命令。

答案 3 :(得分:7)

运行:可以很多,并且可以在构建流程中使用,例如安装多个库

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

答案 4 :(得分:6)

现有答案涵盖了任何在研究此问题时需要的人。因此,我将仅介绍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

答案 5 :(得分:5)

  

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

来自docker文件参考

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

答案 6 :(得分:2)

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

答案 7 :(得分:2)

RUN命令: 在构建映像时,RUN命令基本上将执行默认命令。它还将提交图像更改以进行下一步。

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

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

如果docker文件具有多个1个CMD命令,则除最后一个命令外,所有其他命令均将被忽略。因为此命令将不执行任何操作,而只是设置默认命令。

答案 8 :(得分:0)

运行 CMD 上有足够的答案。我只想在 ENTRYPOINT 上添加几句话。命令行参数可以覆盖 CMD 参数,而始终使用 ENTRYPOINT 参数。

This article是很好的信息来源。