问题描述
在Dockerfile中使用了两个命令,一个是RUN,一个是CMD。他想知道这两个命令的区别是什么。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在Dockerfile中,RUN和CMD是两个不同的命令,它们的作用和使用方式也不同。
RUN命令
RUN命令在镜像构建过程中执行命令,并将结果提交为新的镜像层。它用于在构建镜像时执行一些命令,比如安装软件包、配置环境等。RUN命令会创建一个临时容器,基于构建过程中的上一步,执行指定的命令。当命令执行完毕后,它会将文件系统的更改作为新的镜像层提交。可以将RUN命令看作是执行docker run
和docker commit
的组合操作,用于生成可复现的镜像。
CMD命令
CMD命令用于指定容器启动时的默认命令。它不会在构建镜像时执行任何操作,而是在启动容器时指定容器的默认命令。如果没有指定CMD命令,Docker会使用镜像中的默认CMD命令。如果在启动容器时指定了其他命令,如docker run $my_image /bin/bash
,则CMD命令将被替换为指定的命令。CMD命令只能有一个值,但可以通过在镜像名称后面添加参数来覆盖默认的CMD命令,例如docker run busybox echo hello
将使用echo hello
命令替换默认的CMD命令。
Shell语法和Exec语法
在Dockerfile中,RUN和CMD命令可以使用Shell语法或Exec语法来指定要执行的命令。Shell语法是指使用字符串形式的命令,命令将在/bin/sh -c
下执行。Shell语法可以用于IO重定向、命令链和变量扩展等。但是,Shell语法会拦截信号,可能在容器停止时引起问题。Exec语法是指直接在操作系统中执行命令,不使用Shell。Exec语法更适合处理信号,但缺少Shell的其他功能。当在Entrypoint和CMD之间链接命令时,通常使用Exec语法。常见的Entrypoint结构如下:
ENTRYPOINT ["/entrypoint.sh"]
CMD ["server", "arg1", "arg2"]
在上面的示例中,我们定义了一个Entrypoint脚本entrypoint.sh
,然后使用Exec语法执行CMD命令。
请注意,以上解决方案中的CMD命令是默认的CMD命令,可以根据实际情况进行修改。