Dockerfile 中的 CMD和ENTRYPOINT 两兄弟
CMD
先说老大 CMD
当一个容器准备好运行之后,需要找一个指定命令来创建一个初始进程并运行。
一,/bin/sh -c
因为某种意义上一个Dockerfile其实可以理解是一个简化版bash 脚本,所以一般情况下,我们可以像写bash命令一样使用CMD来指定使用bash来运行命令。
比如:
CMD echo 'hello world!'
这样,容器创建之后,就会使用/bin/sh -c来运行上述命令,如下所示:
/bin/sh -c 'echo hello world!'
二, 直接运行可执行程序
如果我们不想是用/bin/sh而是直接运行一个可执行程序的话,怎么办呢?这种情况下,可以使用CMD命令的另外一种形式,如下:
CMD ["echo", "hello world!"]
这样,容器准备好以后就会直接创建一个进程来运行echo这个程序 (/bin/echo),打印出"hello world!"。
使用CMD有一个好处就是在使用docker run命令运行容器时可以使用command参数来覆盖CMD缺省指定的命令。比如:
docker run -it test:latest echo 'hello world!'
ENTRYPOINT
其实ENTRYPOINT是老大,它比CMD优先级更高
我们也可以使用ENTRYPOINT来指定容器初始程序,可以是bash /bin/sh, 也可以是其他可执行程序。语法和CMD的相似。比如:
#/bin/sh -c
ENTRYPOINT echo 'hello world!'
#exeutable
ENTRYPOINT ["echo", "hello world!"]
两兄弟如何相处
一 EntryPoint 老大
CMD可以指定容器运行入口。但ENTRYPOINT作为entry point,有不可置疑的地位。它是老大,只有它不在的时候,CMD才能当老大。那么它在的时候CMD是什么地位呢?这要看它以什么方式存在,如果是使用/bin/sh -c来启动容器,那么没有CMD什么事了。如果是使用其他可执行程序启动容器,那么CMD指定的所有东东统统作为该可执行程序的后续参数使用。