多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] 参考链接:[https://blog.csdn.net/THMAIL/article/details/85284948](https://blog.csdn.net/THMAIL/article/details/85284948) ### CMD指令格式 ***** `CMD` 指令的格式和 `RUN` 相似,也是两种格式: * `shell` 格式:`CMD <命令>` * `exec` 格式:`CMD ["可执行文件", "参数1", "参数2"...]` * 参数列表格式:`CMD ["参数1", "参数2"...]`。在指定了 `ENTRYPOINT` 指令后,用 `CMD` 指定具体的参数。 在指令格式上,一般推荐使用 `exec` 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 `"`,而不要使用单引号。 如果使用 `shell` 格式的话,实际的命令会被包装为 `sh -c` 的参数的形式进行执行。比如: ``` CMD echo $HOME ``` 在实际执行中,会将其变更为: ``` CMD [ "sh", "-c", "echo $HOME" ] ``` ### Dockerfile CMD示例 ***** 如果将 `CMD` 写为: ``` CMD service nginx start ``` 然后发现容器执行后就立即退出了。甚至在容器内去使用 `systemctl` 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。 ` ` 而使用 `service nginx start` 命令,则是希望 upstart 来以后台守护进程形式启动 `nginx` 服务。而刚才说了 `CMD service nginx start` 会被理解为 `CMD [ "sh", "-c", "service nginx start"]`,因此主进程实际上是 `sh`。那么当 `service nginx start` 命令结束后,`sh` 也就结束了,`sh` 作为主进程退出了,自然就会令容器退出。 正确的做法是直接执行 `nginx` 可执行文件,并且要求以前台形式运行。比如: ``` CMD ["nginx", "-g", "daemon off;"] ``` ### CMD总结 ***** Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。 对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。