在 docker 中建構鏡像最常用的方式,就是使用 dockerfile 。dockerfile 是一個用來建構鏡像的文本檔案,文本内容包含了一條條建構鏡像所需的指令和說明。官方文檔:https://docs.docker.com/engine/reference/builder/
from
文法: from <image>:<tag>
指明建構的新鏡像是來自于哪個基礎鏡像,如果沒有選擇 tag,那麼預設值為 latest。
注:如果不以任何鏡像為基礎,那麼寫法為:from scratch。官方說明:scratch 鏡像是一個空鏡像,可以用于建構 busybox 等超小鏡像,可以說是真正的從零開始建構屬于自己的鏡像。
maintainer(deprecated)
文法: maintainer <name>
指明鏡像維護者及其聯系方式(一般是郵箱位址)。官方說明已過時,推薦使用 label。
label
文法: label <key>=<value> <key>=<value> <key>=<value> ...
功能是為鏡像指定标簽。也可以使用 label 來指定鏡像作者。
run
文法: run <command>
建構鏡像時運作的 shell 指令,比如建構的新鏡像中我們想在 /usr/local 目錄下建立一個 java 目錄。
add
文法: add <src>... <dest>
拷貝檔案或目錄到鏡像中。src 可以是一個本地檔案或者是一個本地壓縮檔案,壓縮檔案會自動解壓。還可以是一個 url,如果把 src 寫成一個 url,那麼 add 就類似于 wget 指令,然後自動下載下傳和解壓。
copy
文法: copy <src>... <dest>
拷貝檔案或目錄到鏡像中。用法同 add,隻是不支援自動下載下傳和解壓。
expose
文法: expose <port> [<port>/<protocol>...]
暴露容器運作時的監聽端口給外部,可以指定端口是監聽 tcp 還是 udp,如果未指定協定,則預設為 tcp。如果想使得容器與主控端的端口有映射關系,必須在容器啟動的時候加上 -p 參數。
env
文法: env <key> <value> 添加單個, env <key>=<value> ... 添加多個。
設定容器内環境變量。
cmd
文法:
cmd ["executable","param1","param2"] ,比如:cmd ["/usr/local/tomcat/bin/catalina.sh", "run"]
cmd ["param1","param2"] ,比如: cmd [ "echo", "$java_home" ]
cmd command param1 param2 ,比如: cmd echo $java_home
啟動容器時執行的 shell 指令。在 dockerfile 中隻能有一條 cmd 指令。如果設定了多條 cmd,隻有最後一條 cmd 會生效。
如果建立容器的時候指定了指令,則 cmd 指令會被替代。假如鏡像叫 centos:7 ,建立容器時指令是: docker run -it --name centos7 centos:7 echo "helloworld" 或者 dockerrun -it --name centos7 centos:7
/bin/bash ,就不會輸出 $java_home 的環境變量資訊了,因為 cmd 指令被 echo "helloworld" 、/bin/bash 覆寫了。
entrypoint
entrypoint ["executable", "param1", "param2"] ,比如: entrypoint ["/usr/local/tomcat/bin/catalina.sh", "run"]
entrypoint command param1 param2 ,比如: entrypoint ehco $java_home
啟動容器時執行的 shell 指令,同 cmd 類似,不會被 docker run 指令行指定的參數所覆寫。在dockerfile 中隻能有一條 entrypoint 指令。如果設定了多條 entrypoint,隻
有最後一條entrypoint 會生效。
如果在 dockerfile 中同時寫了 entrypoint 和 cmd,并且 cmd 指令不是一個完整的可執行指令,那麼 cmd 指定的内容将會作為 entrypoint 的參數;如果在 dockerfile 中
同時寫了 entrypoint 和 cmd,
并且 cmd 是一個完整的指令,那麼它兩會互相覆寫,誰在最後誰生效。
workdir
文法: workdir /path/to/workdir
為 run、cmd、entrypoint 以及 copy 和 and 設定工作目錄。
volume
指定容器挂載點到主控端自動生成的目錄或其他容器。一般的使用場景為需要持久化存儲資料時。
一般不會在 dockerfile 中用到,更常見的還是在 docker run 的時候通過 -v 指定資料卷。
dockerfile 檔案編寫好以後,真正建構鏡像時需要通過 docker build 指令。
docker build 指令用于使用 dockerfile 建立鏡像。
-f :指定要使用的 dockerfile 路徑;
--tag, -t :鏡像的名字及标簽,可以在一次建構中為一個鏡像設定多個标簽。
關于 . 了解
我們在使用 docker build 指令去建構鏡像時,往往會看到指令最後會有一個 . 号。它究竟是什麼意思呢?
很多人以為是用來指定 dockerfile 檔案所在的位置的,但其實 -f 參數才是用來指定dockerfile 的路徑的,那麼 . 号究竟是用來做什麼的呢?
docker 在運作時分為 docker 引擎(服務端守護程序) 和 用戶端工具,我們日常使用各種docker 指令,其實就是在使用 用戶端工具 與 docker 引擎 進行互動。
當我們使用 docker build 指令來建構鏡像時,這個建構過程其實是在 docker 引擎 中完成的,而不是在本機環境。如果在 dockerfile 中使用了一些 add 等指令來操作檔案,如何讓
docker 引擎擷取到這些檔案呢?
這裡就有了一個 鏡像建構上下文 的概念,當建構的時候,由使用者指定建構鏡像時的上下文路徑,而docker build 會将這個路徑下所有的檔案都打包上傳給 docker 引擎,引擎内将這
些内容展開後,就能擷取到上下文中的檔案了。
舉個栗子:我的主控端 jdk 檔案在 /root 目錄下,dockerfile 檔案在 /usr/local/dockerfile 目錄下,檔案内容如下:
那麼建構鏡像時的指令就該這樣寫:
再舉個栗子:我的主控端 jdk 檔案和 dockerfile 檔案都在 /usr/local/dockerfile 目錄下,檔案内容如下:
那麼建構鏡像時的指令則這樣寫:
接下來我們通過基礎鏡像 centos:7 ,在該鏡像中安裝 jdk 和 tomcat 以後将其制作為一個新的鏡像 mycentos:7 。
建立目錄。
編寫 dockerfile 檔案。
dockerfile 檔案内容如下:
建構鏡像。
太棒了,dockerfile 建構鏡像的方式你也學會了,再接再厲學習一下 docker 鏡像的備份恢複遷移,go ~