Dockerfile 中 CMD 、RUN 和 ENTRYPOINT的区别和使用时机


文章目录

  • Dockerfile 中 CMD 、RUN 和 ENTRYPOINT的区别和使用时机
  • 1. CMD 和 RUN 的区别
  • 2. CMD 和 ENTRYPOINT的区别
  • 2.1 在 shell 写法环境下
  • 2.2 在 exec 写法环境下


1. CMD 和 RUN 的区别

两者都是用于执行命令,区别在于执行命令的时机不同,RUN命令适用于在 docker build 构建docker镜像时执行的命令,而CMD命令是在 docker run 执行docker镜像构建容器时使用,可以动态的覆盖CMD执行的命令。

2. CMD 和 ENTRYPOINT的区别

首先,CMD命令是用于默认执行的,且如果写了多条CMD命令,则只会执行最后一条,如果后续存在ENTRYPOINT命令,则CMD命令或被充当参数或者覆盖,而且Dockerfile中的CMD命令最终可以被在执行 docker run命令时添加的命令所覆盖。而ENTRYPOINT命令则是一定会执行的,一般用于执行脚本
根据写法分析,这里涉及到执行命令的两种写法,第一种使用 shell,第二种使用 exec,例如

#shell写法
FROM centos
CMD echo 'hello'

#exec写法
FROM centos
CMD ["echo","hello"]

2.1 在 shell 写法环境下

在shell写法中,如果存在 ENTRYPOINT命令,则不管是在Dockerfile中存在CMD命令也好,还是在 docker run执行的后面添加的命令也好,都不会被执行。如果不存在 ENTRYPOINT命令,则可以被 docker run后面设置的命令覆盖,实现动态执行命令操作。

2.2 在 exec 写法环境下

在shell写法中,如果存在 ENTRYPOINT命令,则在Dockerfile中如果存在CMD命令或者是在 docker run执行的后面添加的命令,会被当做 ENTRYPOINT命令的参数来使用。举例如下

FROM centos
CMD ["hello"]
ENTRYPOINT ["echo"]

使用 docker run xxx 后,显示打印 hello,此时 CMD命令的内容会被充当ENTRYPOINT命令的参数,且这种情况,CMD命令的内容不会被ENTRYPOINT命令覆盖,还可以支持在docker run 后面的命令覆盖 Dockerfile中的CMD命令。
例如:执行 docker run xx helllo-docker , 会显示打印 hello-docker,可以得出 此时 docker run后面的内容将Dockerfile中的最后一条CMD命令的参数内容覆盖,搭配ENTRYPOINT命令使用。这种方法较常用,可以支持动态修改参数内容,保存执行命令一样。