CMD
指令的格式和 RUN
相似,也是两种格式:shell
格式:CMD <命令>
exec
格式:CMD ["可执行文件", "参数1", "参数2"...]
CMD ["参数1", "参数2"...]
。在指定了 ENTRYPOINT
指令后,用 CMD
指定具体的参数。CMD
指令就是用于指定默认的容器主进程的启动命令的。ubuntu
镜像默认的 CMD
是 /bin/bash
,如果我们直接 docker run -it ubuntu
的话,会直接进入 bash
。我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release
。这就是用 cat /etc/os-release
命令替换了默认的 /bin/bash
命令了,输出了系统版本信息。exec
格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 "
,而不要使用单引号。shell
格式的话,实际的命令会被包装为 sh -c
的参数的形式进行执行。比如:CMD
就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。systemd
去启动后台服务,容器内没有后台服务的概念。CMD
写为:systemctl
命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。service nginx start
命令,则是希望 upstart 来以后台守护进程形式启动 nginx
服务。而刚才说了 CMD service nginx start
会被理解为 CMD [ "sh", "-c", "service nginx start"]
,因此主进程实际上是 sh
。那么当 service nginx start
命令结束后,sh
也就结束了,sh
作为主进程退出了,自然就会令容器退出。nginx
可执行文件,并且要求以前台形式运行。比如: