Dockerfile 寫起來相信大家都有一個疑問, ENTRYPOINT 和 CMD 的分別是什麼?
根據 Docker 的官方文檔
An
ENTRYPOINT
allows you to configure a container that will run as an executable.
The main purpose of a CMD is to provide defaults for an executing container.
看完也不太懂, 繼續向下看
Both
CMD
andENTRYPOINT
instructions define what command gets executed when running a container. There are few rules that describe their co-operation.
- Dockerfile should specify at least one of
CMD
orENTRYPOINT
commands.ENTRYPOINT
should be defined when using the container as an executable.CMD
should be used as a way of defining default arguments for anENTRYPOINT
command or for executing an ad-hoc command in a container.CMD
will be overridden when running the container with alternative arguments.
結論
簡單直接, ENTRYPOINT 是 Image 運行時 Container 要運行的 Executable
而 CMD 是 ENTRYPOINT 預設的 Argument (參數), 執行時可以被命令行取代
舉個例子, 這個 Dockerfile
運行起來
# Ping 127.0.0.1 docker run test # Ping 8.8.8.8 docker run test 8.8.8.8
注意事項
1. ENTRYPOINT 和 CMD 都有兩個格式 (JSON Array 和 shell), 官方文檔舉的例子
其中一個用了 shell 格式的話,
紅字部分, CMD 被忽略了, 無法達到我們預期的效果
藍字部分, /bin/sh -c 亂入了, 會令執行起來添加多了一個 bash 進程, PID 不是 1
簡單說, 用 JSON Array 格式就不會錯了
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
2. ENTRYPOINT 和 CMD 在 Dockerfile 忽略不填的話, 會繼承母 Image 的數值
3. 填寫 ENTRYPOINT 必須同時填寫 CMD, 因為重寫 ENTRYPOINT 會清空 CMD 數值
命令懶人包
# 直接運行 (套用預設 ENTRYPOINT + CMD) docker run test # 修改 CMD 運行 (只套用預設 ENTRYPOINT) docker run test 8.8.8.8 # 修改 ENTRYPOINT 運行 (只套用預設 CMD, 無法這樣使用!) # docker run --entrypoint=nslookup test # 修改 ENTRYPOINT + CMD 運行 docker run --entrypoint=nslookup test 8.8.8.8
另外 Override ENTRYPOINT 的話不能直接在 ENTRYPOINT 提供 Argument
需要 Argument 的話要再在後面 CMD 的位置提供
參考: https://medium.com/@oprearocks/how-to-properly-override-the-entrypoint-using-docker-run-2e081e5feb9d