![](/img/trans.png)
[英]Understanding the difference in sequence of ENTRYPOINT/CMD between Dockerfile and docker run
[英]Difference between RUN and CMD in a Dockerfile
我對什么時候應該使用CMD
與RUN
感到困惑。 例如,要執行 bash/shell 命令(即ls -la
),我將始終使用CMD
或者是否存在使用RUN
? 試圖了解關於這兩個類似Dockerfile
指令的最佳實踐。
RUN是一個鏡像構建步驟, RUN
命令后容器的狀態將被提交到容器鏡像。 一個 Dockerfile 可以有許多RUN
步驟,這些步驟相互疊加以構建映像。
CMD是當您啟動構建的鏡像時容器默認執行的命令。 Dockerfile 將只使用最終定義的CMD
。 使用docker run $image $other_command
啟動容器時,可以覆蓋CMD
。
ENTRYPOINT也與CMD
密切相關,可以修改容器啟動鏡像的方式。
RUN
- 命令在我們構建 docker 鏡像時觸發。
CMD
- 命令在我們啟動創建的 docker 鏡像時觸發。
我發現這篇文章非常有助於理解它們之間的區別:
RUN - RUN 指令允許您安裝您的應用程序和所需的包。 它在當前圖像之上執行任何命令,並通過提交結果創建一個新層。 通常,您會在 Dockerfile 中找到多個 RUN 指令。
CMD - CMD 指令允許您設置默認命令,該命令僅在您運行容器而不指定命令時執行。 如果 Docker 容器使用命令運行,則默認命令將被忽略。 如果 Dockerfile 有一個以上的 CMD 指令,除了最后一條指令
CMD 指令被忽略。
RUN - 安裝 Python ,您的容器現在已將 Python燒錄到其映像中
CMD - python hello.py ,運行你喜歡的腳本
現有答案涵蓋了查看此問題的任何人所需的大部分內容。 所以我將只介紹 CMD 和 RUN 的一些利基領域。
GingerBeer 提出了一個重要觀點:如果你輸入多個 CMD,你不會得到任何錯誤 - 但這樣做很浪費。 我想用一個例子來詳細說明:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
如果你將它構建到一個鏡像中並在這個鏡像中運行一個容器,那么正如 GingerBeer 所說,只有最后一個 CMD 會被注意。 所以該容器的輸出將是:
執行 CMD 2
我的想法是“CMD”正在為正在構建的整個圖像設置一個全局變量,因此連續的“CMD”語句只是覆蓋對該全局變量的任何先前寫入,並且在構建的最終圖像中最后一個寫勝。 由於 Dockerfile 按從上到下的順序執行,我們知道最底層的 CMD 是獲得最后“寫入”的那個(比喻地說)。
關於 RUN 需要注意的一個微妙點是,即使有副作用,它也被視為純函數,因此被緩存。 這意味着如果 RUN 有一些不會改變結果圖像的副作用,並且該圖像已經被緩存,那么 RUN 將不會再次執行,因此在后續構建中不會發生副作用。 例如,以這個 Dockerfile 為例:
FROM busybox
RUN echo "Just echo while you work"
第一次運行它時,你會得到這樣的輸出,帶有不同的字母數字 ID:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
請注意,echo 語句是在上面執行的。 第二次運行它時,它使用緩存,並且您不會在構建的輸出中看到任何回聲:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Using cache
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
注意:不要將 RUN 與 CMD 混淆。 RUN 實際運行一個命令並提交結果; CMD 在構建時不執行任何操作,而是指定映像的預期命令。
來自 docker 文件參考
RUN 命令:RUN 命令基本上會在我們構建映像時執行默認命令。 它還將為下一步提交圖像更改。
可以有 1 個以上的 RUN 命令,以幫助構建新映像的過程。
CMD 命令:CMD 命令只會為新容器設置默認命令。 這不會在構建時執行。
如果一個 docker 文件有 1 個以上的 CMD 命令,那么除了最后一個之外,所有這些命令都會被忽略。 由於此命令不會執行任何操作,只會設置默認命令。
RUN : 可以很多,在構建過程中使用,例如安裝多個庫
CMD : 只能有 1 個,這是你的執行起點(例如["npm", "start"]
, ["node", "app.js"]
)
關於RUN和CMD已經有足夠的答案了。 我只想在ENTRYPOINT上添加幾句話。 CMD參數可以被命令行參數覆蓋,而ENTRYPOINT參數總是被使用。
這篇文章是一個很好的信息來源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.