Docker#3 - Dockerfile 指令解說
前言
當我們採取 docker run 啟動一個容器,若要移轉到另一台機器時,會使用 docker export
和 docker import
這兩個指令做匯出、匯入容易,但是喔半遇到龐大的匯出資料或映像的時候,可能會發生不預期的事情發生。
此時利用 Docker 客製化的方式將製作映像的過程都寫在一個檔案上,讓過程可以獨立一點,放到其他機器上時,能夠根據組態建立對應的映像,就會是一個相當不錯的解決方案了。
關於 Dockerfile 檔案
是用來做自動化建構映像的設定檔案,可以知道所有映像檔的組成,檔案小,容易分享,也方便實現映像的移植。這個檔案沒有副檔名,但卻是由每一行指令組成的文字檔案,命令不分大小寫。
基礎指令
# 開頭為註解
1 | # test comment |
FROM
通常第一行指令行,指定哪一個 image 作為基底來建構,它允許多個 FROM 指令
1 | FROM <images> |
MAINTAINER
此指令用途是提供映像檔的作者資訊
1 | MAINTAINER <name> |
控制指令
RUN
執行指定的指令,在建立映像檔過程對於很多個操作,每加一個 RUN 就會在基底的映像檔案加上一層資料層,實際上就是 shell 程式執行的操作
1 | RUN <COMMEND> |
例如
1 | RUN mkdir testfolder |
那在環境執行上就會是
1 | $ /bin/sh -c mkdir testfolder |
有些執行 param1 param2 太長的話,可以使用 \
符號來換行,會比較好閱讀
1 | RUN mkdir -p /home/demo |
WORKDIR
指定工作目錄
1 | WORKDIR /usr |
如果發現目錄不存在時,會自動建立
ONBUILD
這個指令是作為其他應用程式基底時執行的指令
A-Image
1 | ONBUILD ADD . /home/tmp |
B映像檔是以A映像檔為基底,則A映像檔中的ONBUILD指令就會被觸發
1 | # 以A映像檔為基底 |
引入指令
COPY
1 | COPY [--chown=<user>:<group>] <來源路徑>... <目標路徑> |
這兩個 ADD
, 與 COPY
指令,差別在 COPY 不能識別網路位置
1 | COPY package.json /usr/src/app/ |
來源路徑可以很多個
1 | COPY hom* /mydir/ |
ADD
這個與 COPY 指令相同,可以將本地端的檔案或目錄加入到映像檔的指定位置
1 | ADD [--chown=<user>:<group>] <來源路徑>... <目標路徑> |
而 ADD 是可以支援網址的,就是可以加入遠端的檔案,如果要加入壓縮檔案 (.gzip/.bzip2, .xz),ADD 是可以直接自動解壓縮,下載後的文件會自動設定為 600,COPY 則不會
執行指令
CMD
設定映像檔啟動為容器的時候要執行的指令,提供了三個格式
1 | # exec 形式 |
容器只會連結一個應用程式,只能存在一個 CMD 指令!! 若你寫了兩個以上的 CMD 就只會最後一行才會執行。
ENTRYPOINT
這組有點像 CMD 指令,但是不會像 CMD 有覆蓋的問題,使用 entrypoint 一定會被執行
1 | ENTRYPOINT ["executable", "param1", "param2"] |
這個在 Dockerfile 也只能有一個 ENTRYPOINT ,若指定多個時,只會有最後一個生效
配置指令
EXPOSE
設定容器對外的通訊埠,提供外界使用(從外部存取容器內程式監聽的連接埠),啟動容器時需要透過 -P,否則會自動分派一個通訊部轉發到指定的埠號,格式如下:
1 | EXPOSE <port> [<port>...] |
ENV
設定環境變數,有兩種格式,覺得第二種比較簡易
1 | ENV <key> <value> |
LABEL
主要是映像檔的 metadata 資訊,中繼資料作為標記
1 | LABEL <key>=<value> <key>=<value> <key>=<value> |
使用方式
1 | LABEL "com.example.vendor"="MARUKO" |
但原則上,每一的執行 LABEL 就會多一層映像層,建議只要寫成一條 LABEL 即可
1 | LABEL com.example.vendor="MARUKO" version="1.0" owner="marukochan" |
USER
指定運行容易的用戶名稱或 UID
1 | USER <user>[:<group>] |
使用方式
1 | RUN groupadd -r tester && useradd -r -g tester tester |
ARG
建立過程時,需要做一些配置或使用變數,這個只有適用於建置的過程,而 ENV則是配置環境變數,會影響映像檔的編譯
1 | ARG param1 |
另外千萬別使用ARG 來配置登入密碼、key 資訊,因為只要使用 docker history 就會都看到了。