前言
CMD 和 ENTRYPOINT 指令都是用來(lái)指定容器啟動(dòng)時(shí)運(yùn)行的命令。
單從功能上來(lái)看,這兩個(gè)命令幾乎是重復(fù)的。單獨(dú)使用其中的一個(gè)就可以實(shí)現(xiàn)絕大多數(shù)的用例。
exec 模式和 shell 模式
CMD 和 ENTRYPOINT 指令都支持 exec 模式和 shell 模式的寫法,所以要理解 CMD 和 ENTRYPOINT 指令的用法,就得先區(qū)分 exec 模式和 shell 模式。
CMD ["executable","param1","param2"] // 這是 exec 模式的寫法,注意需要使用雙引號(hào)。
CMD command param1 param2 // 這是 shell 模式的寫法。
exec 模式
exec 模式是建議的使用模式,因?yàn)楫?dāng)運(yùn)行任務(wù)的進(jìn)程作為容器中的 1 號(hào)進(jìn)程時(shí),我們可以通過(guò) docker 的 stop 命令優(yōu)雅的結(jié)束容器(詳情請(qǐng)參考《在 docker 容器中捕獲信號(hào)》)。
exec 模式的特點(diǎn)是不會(huì)通過(guò) shell 執(zhí)行相關(guān)的命令,所以像 $HOME 這樣的環(huán)境變量是取不到的。
shell 模式
shell 模式時(shí),docker 會(huì)以 /bin/sh -c "task command" 的方式執(zhí)行任務(wù)命令(CMD和ENTRYPOINT不為數(shù)組運(yùn)行)。也就是說(shuō)容器中的 1 號(hào)進(jìn)程不是任務(wù)進(jìn)程而是 bash 進(jìn)程。
CMD和ENTRYPOINT
CMD 指令
CMD 指令的目的是:為容器提供默認(rèn)的執(zhí)行命令。
CMD 指令有三種使用方式,除了 exec 模式和 shell , 還有一種是為 ENTRYPOINT 提供默認(rèn)的參數(shù):
命令行參數(shù)可以覆蓋 CMD 指令的設(shè)置,但是只能是重寫,卻不能給 CMD 中的命令通過(guò)命令行傳遞參數(shù)。
ENTRYPOINT
ENTRYPOINT 指令的目的也是為容器指定默認(rèn)執(zhí)行的任務(wù)。
ENTRYPOINT 指令有兩種使用方式,就是我們前面介紹的 exec 模式和 shell 模式。
指定 ENTRYPOINT 指令為 exec 模式時(shí),命令行上指定的參數(shù)會(huì)作為參數(shù)添加到 ENTRYPOINT 指定命令的參數(shù)列表中。
示例:
FROM ubuntu
ENTRYPOINT [ "top", "-b" ]
運(yùn)行 docker run --rm test1 -c
則容器中PID為1的進(jìn)程為 top -b -c
覆蓋默認(rèn)的 ENTRYPOINT 指令
ENTRYPOINT 指令也是可以被命令行覆蓋的,只不過(guò)不是默認(rèn)的命令行參數(shù),而是需要顯式的指定 --entrypoint 參數(shù)。
示例:
$ docker run --rm --entrypoint hostname test2