命令執行的時機,因爲Dockerfile主要用來構建鏡像,並非是立即生效運行的容器,所以在設計dockerfile時需要知道對應執行命令的時機:
RUN
該RUN指令將在當前鏡像頂部的新層中執行所有命令,並提交結果。生成的提交映像將用於中的下一步。RUN下一次構建期間,指令緩存不會自動失效。類似指令的緩存 RUN apt-get dist-upgrade -y將在下一次構建中重用。RUN指令的緩存可以通過使用–no-cache 標誌來使無效,例如docker build --no-cache
docs.docker.com/engine/reference/builder/#run
格式
run的兩種格式
RUN <command>
(shell form,命令在shell中運行,默認情況下/bin/sh -c
在Linux 或cmd /S /C
在Windows 上運行)RUN ["executable", "param1", "param2"]
(exec form)
注意:要使用/ bin / sh
以外的其他shell,請使用exec形式傳入所需的shell。例如: RUN ["/bin/bash", "-c", "echo hello"]
CMD
CMD指令中只能有一條指令Dockerfile。如果您列出多個,CMD 則只有最後一個CMD纔會生效。主要目的CMD是爲執行中的容器提供默認值。這些默認值可以包含可執行文件,也可以省略可執行文件,在這種情況下,您還必須指定一條ENTRYPOINT 指令。
docs.docker.com/engine/reference/builder/#cmd
格式
cmd的三種格式
CMD ["executable","param1","param2"]
(exec形式,這是首選形式)CMD ["param1","param2"]
(作爲ENTRYPOINT的默認參數)CMD command param1 param2
(shell形式)
注意:如果CMD用於提供ENTRYPOINT 指令的默認參數,則CMD和ENTRYPOINT指令均應使用JSON數組格式指定。exec表單被解析爲JSON數組,這意味着您必須在單詞而非單引號(’)周圍使用雙引號(“)。請勿將RUN與CMD混淆。RUN實際上運行命令並提交結果;CMD在生成時不執行任何操作,但指定鏡像的預期命令。
ENTRYPOINT
ENTRYPOINT允許您配置將作爲可執行文件運行的容器。
docs.docker.com/engine/reference/builder/#entrypoint
格式
ENTRYPOINT兩種方式
ENTRYPOINT ["executable", "param1", "param2"]
(exec form,首選)ENTRYPOINT command param1 param2
(shell形式)
注意:Dockerfile只有中的最後一條ENTRYPOINT指令纔會生效
最後
RUN:可多條,執行命令並創建新的Image Layer,可緩存用於下一步的RUN
CMD:只能有一條,設置容器啓動後默認執行的命令和參數
ENTRYPOINT:設置容器啓動時運行的命令,讓容器以應用程序或者服務的形式運行,不會被忽略,一定會執行
一般會有以下兩種書寫格式:
Shell格式:
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
Exec格式:
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/bash","-c","echo hello docker"]
瞭解CMD和ENTRYPOINT如何相互作用
CMD
和ENTRYPOINT
指令都定義了運行容器時要執行的命令。很少有規則描述他們的合作。
-
Dockerfile應該指定CMD或ENTRYPOINT命令中的至少一個。
-
當使用容器作爲可執行文件時,應該定義ENTRYPOINT。
-
CMD應該被用作定義ENTRYPOINT命令或在容器中執行臨時命令的默認參數的一種方式。
-
當使用替代參數運行容器時,將重寫CMD。
下表顯示了對不同的ENTRYPONT/CMD組合執行的命令:
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 |