接下來兩天要來學習所有Dockerfile指令的解釋以及使用方法,雖然直接實做當然是最快的學習方法,但是閱讀完全部的文件再使用才是讓基底穩健的方式。
Dockerfile是Docker在建置image時依照的配置檔案,檔案格式為YAML,由於使用YAML格式,所以註解是使用#
,而Docker會在執行先過濾掉註解。在Dockerfile裡面包含了建置的設定也可以加入多個命令指令,建置image除了使用原生也可以使用BuildKit,多了一些優點不過這不是今天的目標所以略過。BuildKit連結
要建立image需要透過build指令使用
docker build .
# 於當前路徑下尋找Dockerfile來建置image
單純使用build不加其他參數,會自動尋找Dockerfile名稱的YAML來執行,那當然除了叫Dockerfile也可以改成其他名字,只是需要加上-f
flag讓Docker找到正確的路徑,而路徑可以是本機路徑也可以是一段網址
$ docker build -f /another/way/to/build/Dockerfile .
使用-t
flag可以為建置的image標記名稱
$ docker build -t buildme/help .
# 如果要多個名稱就繼續加-t下去,例如-t image/one -t image/two
跟.gitignore以及其他同類型的檔案一樣,如果有需要排除的檔案像是在COPY時不想搬過去的,可以寫在.gitignore裡面
# ignore .git
.git
# ignore all markdown files (md)
*.md
可以透過在檔案最上方配置Dockerfile的解析設置,如果要使用Parser directives需要遵守幾個規則,像是最後的指令後面需要空一行,重複的指令視為無效,寫在配置及命令後視為無效,寫在註解後也是無效。
Parser directives支援syntax
以及escape
,詳細就看Parser directives說明
環境變數就像是程式的變數一樣,可以將值儲存起來使用,關鍵字是ENV
,使用方法是用${}
包起來
FROM node:current-slim
ENV Cool /var
WORKDIR ${Cool}
COPY \$Cool .
VSCode顯示了一些常用的環境變數
從FROM
flag 可以知道新的build要建置,一個Dockerfile必須至少要有一個FROM來開頭,官方文件提供的FROM格式有三種
FROM [--platform=<platform>] <image> [AS <name>]
# or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
# or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
--platform
flag是在需要使用多平台image情況下可以使用來指定image的平台,像是linux/amd64 or windows/amd64這種的
如上環境變數那段使用的FROM,代表我們要從公共庫拉出node且tag是current-slim
的image
FROM node:current-slim
剛剛雖然說FROM必須在最開頭,但其實ARG可以是個例外,為甚麼呢,因為如果在FROM之前設置的ARG是在建置之外使用的,可以想像他被特別抽出了,也代表除了FROM之後都不能使用。
ARG的功用可以當成自定義帶入的參數,能夠在build的時候加上--build-arg <varname>=<value>
的flag來帶入。
RUN在Day3 開始體驗Docker吧(二)有簡單解說過
RUN可以有兩種執行形式
RUN <command>
使用commandRUN ["executable", "param1", "param2"]
使用JSON格式的執行表格RUN 會在當前image的頂端的new layer執行,再來才會創建image,通常用來安裝套件。
Dockerfile只會執行一個CMD指令,如果有多個就只會執行最後一個。
CMD共有三種執行格式
CMD ["executable","param1","param2"]
預設的執行表格CMD ["param1","param2"]
提供給ENTRYPOINT預設參數CMD command param1 param2
shell的執行雖然看起來CMD跟RUN看起來很像但是兩個的差距甚大,RUN就是直接執行指令,而CMD則類似將指令提交給image,所以才會將安裝套件放置CMD
label就如同名稱一樣,幫我們的image別上標籤,必須依照<key>=<value>
的方法來定義標籤,有沒有發現跟Kubernetes一樣呢。
別上標籤的image目前看到是可以使用filter用來篩選image,或是利用第三方套件來使用。
透過仔細閱讀指令的方式將Dockerfile了解的更透徹了,明天將繼續把剩餘的指令了解完。明天還要補班的各位辛苦拉,小的也是受(害者)眾之一,各位一起努力吧。
參考文獻:
docker官方文件