Answers:
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", "daemon off;"]
运行 -安装Python,您的容器现在将python刻录到其映像中
CMD -python hello.py,运行您喜欢的脚本
注意:不要将RUN与CMD混淆。RUN实际上运行命令并提交结果。CMD在生成时不执行任何操作,但会指定映像的预期命令。
来自docker文件参考
现有的答案涵盖了任何关注此问题的人所需要的大部分内容。因此,我将仅介绍CMD和RUN的一些细分领域。
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