CMD的官方说法:类似 RUN 指令,在docker run 时运行, Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run “命令行参数中指定要运行的程序” 所覆盖。
解释下这个是什么意思。
我们使用终端交互新建一个容器,命令是 docker run -it test125 /bin/bash 。
“/bin/bash”这部分就是 “命令行参数中指定要运行的程序”,后面简称“指定程序”。这部分和CMD的作用是一样的。多个CMD指令只能生效一个,也作用与“指定程序”。当CMD和指定程序同时存在时,以“指定程序”的命令为准。
看一段dockerfile
from centos
CMD "/bin/bash"
使用上面的dockerfile,就不用在执行时写“/bin/bash”,因为CMD已经写上了,效果都是一样的。
再一段dockerfile
from centos
CMD "echo 'aaa' "
使用上面的dockerfile。执行 docker run test125 echo "bbb"。最后会输出 bbb。因为“指定程序”生效,CMD被覆盖。
RUN的官方说法:用于执行后面跟着的命令行命令
这个理解起来比较简单,build时按顺序执行RUN的命令。指定程序怎么写和RUN也没什么关系。RUN 会先于 CMD、ENTRYPOINT执行。
ENTRYPOINT的官方说法:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
先解释这句话
但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
意思是 CMD 和 “指定程序”,都类似于默认值,当存在ENTRYPOINT,以ENTRYPOINT为准。他们三个到实际执行其实都是一个东西,只能有一个被执行。
再用docker run test125 echo "bbb" 执行这个dockerfile。
from centos
CMD "echo 'aaa' "
ENTRYPOINT "echo 'ccc' "
最后输出的是 ccc ,就是因为ENTRYPOINT 优先级高于CMD 和 “指定程序”。
再说下 “而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序”这句话。
看下面这个dockerfile
from centos
CMD ["fff"]
ENTRYPOINT ["echo"]
在用exec 格式写cmd和entrypint时。CMD 可以作为 entrypint的默认参数。
用 docker run -it test125 ,将两条命令合并,执行 echo "fff",输出fff。
再用 docker run -it test125 "ccc" ,执行下来输出 ccc。说明指令指定的ccc 覆盖了cmd的 fff。就是这个意思。