CMD
和RUN
感到困惑。例如,要执行bash / shell命令(即ls -la
),我将始终使用CMD
,或者是否存在使用RUN
的情况?试图了解有关这两个类似的Dockerfile
指令的最佳实践。#1 楼
RUN是映像构建步骤,在执行RUN
命令后,容器的状态将提交到容器映像。一个Dockerfile可以具有许多RUN
步骤,这些步骤彼此叠加以构建映像。 CMD是启动构建映像时默认情况下容器执行的命令。 Dockerfile将仅使用最终定义的
CMD
。使用CMD
启动容器时,可以覆盖docker run $image $other_command
。 ENTRYPOINT也与
CMD
密切相关,可以修改容器启动图像的方式。评论
您需要执行所有RUN来设置您的环境,并且(仅)CMD启动了在您的容器中运行的进程,例如,对于nginx,请从github.com/nginxinc/docker-nginx/blob/中提取…,您会看到CMD [ “ nginx”,“-g”,“守护程序关闭”;]]
–user2915097
16年5月26日14:00
“一个Dockerfile只能有一个CMD”-从技术上讲不是正确的,但实际上除一个以外的所有内容都将被忽略。请参阅GingerBeer的答案。
– Colm Bhandal
20-4-19上午10:42
“ Dockerfile将仅使用定义的最终CMD”?实际上,最终定义的CMD将在启动映像时用作容器,对吗?
–张保罗
20-05-29在13:19
是@paulcheung,将dockerfile中的最终命令写入该映像,并且该命令是容器在您启动生成的映像时默认执行的命令。
–马特
20-05-31在23:35
#2 楼
RUN
-在构建docker映像时触发命令。CMD
-在启动创建的docker映像时触发命令。#3 楼
我发现本文对理解它们之间的区别非常有帮助:RUN-
RUN指令允许您安装应用程序和所需的程序包。它会在当前图像的顶部执行任何命令
,并通过提交结果来创建新层。通常,您会在Dockerfile中找到多个RUN指令。
CMD-
CMD指令允许您设置默认命令,只有当您执行该命令时,它才会被执行
在不指定命令的情况下运行容器。
如果Docker容器通过命令运行,则默认命令将被忽略。如果Dockerfile具有多个CMD指令,则除最后一个
以外的所有CMD指令都将被忽略。
#4 楼
运行-安装Python,您的容器现在已将python刻录到其映像中CMD-python hello.py,运行您喜欢的脚本
评论
CMD-安装Python,我的容器现在没有列出烧入其图像的python吗?
–卡洛斯·丰特斯
18-10-23在3:40
RUN将创建python的图像层,CMD将仅执行命令而不创建图像
– Rohit Salecha
18-10-25在13:25
#5 楼
RUN命令:在构建映像时,RUN命令将基本上执行默认命令。它还将提交映像更改以进行下一步。
可以有多个RUN命令,以帮助构建新映像。
CMD命令:
CMD命令将为新容器设置默认命令。这不会在构建时执行。
如果docker文件具有多个1个CMD命令,则除最后一个命令外,所有命令均被忽略。因为此命令将不执行任何操作,而只是设置默认命令。
#6 楼
注意:不要将RUN与CMD混淆。 RUN实际上会运行命令,并且
提交结果; CMD在生成时不执行任何操作,但
指定映像的预期命令。
来自docker文件参考
https:// docs.docker.com/engine/reference/builder/#cmd
#7 楼
RUN:可以很多,并且在构建过程中使用,例如安装多个库CMD:只能有1,这是您的执行起点(例如
["npm", "start"]
,["node", "app.js"]
)#8 楼
现有的答案涵盖了任何关注此问题的人所需要的大部分内容。因此,我只介绍CMD和RUN的一些特殊领域。CMD:允许重复但很浪费
GingerBeer提出了一个重要的观点:您不会遇到任何错误如果您输入了多个CMD,则这样做很浪费。我想举一个例子:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
如果将其构建到图像中并在该图像中运行容器,那么按照GingerBeer的说法,只有最后CMD将受到关注。因此,该容器的输出将是:
执行CMD 2
我认为,“ CMD”设置单个全局变量用于生成的整个映像,因此,连续的“ CMD”语句将覆盖先前对该全局变量的所有写入操作,而在构建的最后一个映像中,最后一个要写入的变量将获胜。由于Dockerfile是从上到下依次执行的,因此我们知道最底层的CMD是获得最终“写入”的CMD(隐喻地说)。缓存
关于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
#9 楼
关于RUN和CMD的答案已经足够了。我只想在ENTRYPOINT上添加几句话。命令行参数可以覆盖CMD参数,而始终使用ENTRYPOINT参数。本文是很好的信息来源。
评论
docs.microsoft.com/en-us/virtualization/windowscontainers/…