Dockerfile指令详解: CMD 容器启动命令
CMD 容器啟動命令
CMD 指令的格式和 RUN 相似,也是兩種格式:
- shell 格式:CMD <命令>
- exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]
- 參數(shù)列表格式:CMD ["參數(shù)1", "參數(shù)2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具體的參數(shù)。
之前介紹容器的時候曾經(jīng)說過,Docker 不是虛擬機,容器就是進程。既然是進程,那么在啟動容器的時候,需要指定所運行的程序及參數(shù)。CMD 指令就是用于指定默認的容器主進程的啟動命令的。
在運行時可以指定新的命令來替代鏡像設置中的這個默認命令,比如,ubuntu 鏡像默認的 CMD 是 /bin/bash,如果我們直接 docker run -it ubuntu 的話,會直接進入 bash。我們也可以在運行時指定運行別的命令,如 docker run -it ubuntu cat /etc/os-release。這就是用 cat /etc/os-release 命令替換了默認的 /bin/bash 命令了,輸出了系統(tǒng)版本信息。
在指令格式上,一般推薦使用 exec 格式,這類格式在解析時會被解析為 JSON 數(shù)組,因此一定要使用雙引號 ",而不要使用單引號。
如果使用 shell 格式的話,實際的命令會被包裝為 sh -c 的參數(shù)的形式進行執(zhí)行。比如:
CMD echo $HOME在實際執(zhí)行中,會將其變更為:
CMD [ "sh", "-c", "echo $HOME" ]這就是為什么我們可以使用環(huán)境變量的原因,因為這些環(huán)境變量會被 shell 進行解析處理。
提到 CMD 就不得不提容器中應用在前臺執(zhí)行和后臺執(zhí)行的問題。這是初學者常出現(xiàn)的一個混淆。
Docker 不是虛擬機,容器中的應用都應該以前臺執(zhí)行,而不是像虛擬機、物理機里面那樣,用 systemd 去啟動后臺服務,容器內沒有后臺服務的概念。
一些初學者將 CMD 寫為:
CMD service nginx start然后發(fā)現(xiàn)容器執(zhí)行后就立即退出了。甚至在容器內去使用 systemctl 命令結果卻發(fā)現(xiàn)根本執(zhí)行不了。這就是因為沒有搞明白前臺、后臺的概念,沒有區(qū)分容器和虛擬機的差異,依舊在以傳統(tǒng)虛擬機的角度去理解容器。
對于容器而言,其啟動程序就是容器應用進程,容器就是為了主進程而存在的,主進程退出,容器就失去了存在的意義,從而退出,其它輔助進程不是它需要關心的東西。
而使用 service nginx start 命令,則是希望 upstart 來以后臺守護進程形式啟動 nginx 服務。而剛才說了 CMD service nginx start 會被理解為 CMD [ "sh", "-c", "service nginx start"],因此主進程實際上是 sh。那么當 service nginx start 命令結束后,sh 也就結束了,sh 作為主進程退出了,自然就會令容器退出。
正確的做法是直接執(zhí)行 nginx 可執(zhí)行文件,并且要求以前臺形式運行。比如:
CMD ["nginx", "-g", "daemon off;"]參考鏈接:https://www.kancloud.cn/docker_practice/docker_practice/469789
總結
以上是生活随笔為你收集整理的Dockerfile指令详解: CMD 容器启动命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dockerfile指令详解:ONBUI
- 下一篇: 查询本机公网ip地址的方法