介紹
鏡像的制作方式有兩種
- 基于容器制作,但這樣的鏡像不利于維護,不适合線上使用。
- 另一種就是就是要介紹的Dockerfile,Dockerfile就是建構鏡像的源代碼,當時和我們編寫程式的源代碼不同,Dockerfile是一些指令的組合。
簡要概括Dockerfile的作用:可以讓使用者個性化定制Docker鏡像。因為不同的工作環境需求不同,網絡上已存在的鏡像不能完全滿足自己的需求,此時就需要利用Dockerfile來建構自己可以滿足自己需求的鏡像。
格式
- Dockerfile整體就兩類語句組成:
- 注釋資訊,以 # 辨別的行為注釋行
- 指令參數,一行一個指令。
- Dockerfile檔案名首字母必須大寫。
- Dockerfile指令不區分大小寫,但是為友善和參數做區分,通常指令使用大寫字母。
- Dockerfile中指令按順序從上至下依次執行。
- Dockerfile中第一個非注釋行必須是FROM指令,用來指定制作目前鏡像依據的是哪個基礎鏡像。
- Dockerfile中需要調用的檔案必須跟Dockerfile檔案在同一目錄下,或者在其子目錄下,父目錄或者其它路徑無效。
指令集
FROM
-
指令必須為Dockerfile檔案開篇的第一個非注釋行,用于指定建構鏡像所使用的基礎鏡像,後續的指令運作都要依靠此基礎鏡像所提供的的環境(簡單說就是假如Dockerfile中所引用的基礎鏡像裡面沒有mkdir指令,那後續的指令是沒法使用mkdir參數的。)FROM
- 實際使用中,如果沒有指定倉庫,docker build會先從本機查找是否有此基礎鏡像,如果沒有會預設去Docker Hub Registry上拉取,再找不到就會報錯。
文法
FROM [--platform=<platform>] <image> [AS <name>]
or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
scratch 是最基礎的一個空白鏡像。 下面是官方的centos的Dockerfile

RUN
-
指令将在目前鏡像的頂部中執行所有指令,并送出結果,生成的鏡像将用于下一條指令。RUN
-
下一次建構期間,指令緩存不會自動失效。類似指令的緩存 RUN apt-get dist-upgrade -y将在下一個建構中重用。RUN
指令的緩存可以通過使用–no-cache 标志來使無效,例如docker build --no-cache。RUN
文法
shell形式,指令在shell中運作,預設情況下/bin/sh -c在Linux或cmd /S /CWindows 上運作
參數是一個JSON格式的數組,其中
"executable"
為要運作的指令,後面的"paramN"為傳遞給指令的選項或參數。此格式指定的指令不會以
"/bin/sh-c"
來發起,也就是直接由核心建立,是以不具備shell特性,類似于
RUN [ "echo", "$HOME" ]
,是無法識别 $ 的;如果想要依賴shell特性,可以替換指令為這樣的格式
[ "/bin/sh", "-c", "echo $HOME" ]
。
CMD
- 指定啟動容器的預設要運作的程式,也就是PID為1的程序指令,且其運作結束後容器也會終止。如果不指定,預設是bash。
-
指令指定的預設程式會被docker run指令行指定的參數所覆寫。CMD
- Dockerfile中可以存在多個
指令,但僅最後一個生效。因為一個docker容器隻能運作一個PID為1的程序。CMD
- 類似于
指令,也可以運作任意指令或程式,但是兩者的運作時間點不同,RUN指令運作在docker build的過程中,而CMD指令運作在基于新鏡像啟動容器(docker run)時。RUN
文法
前兩種文法格式同RUN指令。第一種用法對于CMD指令基本沒有意義,因為它運作的程式PID不為1。
CMD command param1 param2
CMD ["executable","param1","param2"](exec形式,這是首選形式)
第三種則需要結合ENTRYPOINT指令使用,CMD指令後面的指令作為ENTRYPOINT指令的預設參 數。如果docker run指令行結尾有參數指定,那CMD後面的參數不生效。
CMD ["param1","param2"](作為ENTRYPOINT的預設參數)
LABEL
- 同docker run -l
- 使用者可以為鏡像指定各種中繼資料(鍵值對的格式)。
文法
可以在一行或者使用 \ 來拼接,來減少鏡像的層,最終減小鏡像的大小。
LABEL multi.label1="value1" multi.label2="value2" other="value3"
or
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
MAINTAINER
已棄用,LABEL要靈活的多。
EXPOSE
- 通知Docker容器在運作時監聽指定的網絡端口。可以指定端口是偵聽TCP還是UDP,如果未指定協定,則預設值為TCP。
- 同
docker run --expose
文法
示例
EXPOSE 80/tcp
EXPOSE 80/udp
ENV
-
指令将環境變量設定為ENV
。此值将在建構階段中所有後續指令的環境中使用。調用格式為<key><value>
$variable_name或者${variable_name}
- 同
docker run -e
文法
ENV <key> <value>
ENV <key>=<value> ...
- 第一種形式,ENV
會将一個變量設定為一個值。第一個空格之後的整個字元串将被視為-包括空格字元。該值将為其他環境變量解釋,是以如果不對引号字元進行轉義,則将其删除。<key> <value>
- 第二種形式ENV
允許一次設定多個變量。請注意,第二種形式在文法中使用等号(=),而第一種形式則不使用等号(=)。像指令行解析一樣,引号和反斜杠可用于在值中包含空格。<key>=<value> ...
- 定義多個變量時,建議使用第二種方式,因為Dockerfile中每一行都是一個鏡像層,建構起來比較吃資源。
ADD
-
指令跟ADD
類似,不過它還支援使用tar檔案和URL路徑。COPY
- 當拷貝的源檔案是tar檔案時,會自動展開為一個目錄并拷貝進新的鏡像中;然而通過URL擷取到的tar檔案不會自動展開。複制或解壓縮目錄時,其行為與相同tar -x。
文法
ADD [--chown=<user>:<group>] <src>... <dest>
or
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] (此格式對于包含空格的路徑是必需的)
規則
- 該路徑必須是内部語境的建構; 不能這樣做ADD …/something /something,因為第一步 docker build是将上下文目錄(和子目錄)發送到docker守護程式。
- 如果是URL,并且不以斜杠結尾,則從URL下載下傳檔案并将其複制到。
- 如果是URL并以斜杠結尾,則從URL推斷檔案名,然後将檔案下載下傳到 /。例如,ADD http://example.com/foobar /将建立檔案/foobar。該URL必須具有非平凡的路徑,以便在這種情況下可以發現适當的檔案名(http://example.com 将不起作用)。
- 如果是目錄,則将複制目錄的整個内容,包括檔案系統中繼資料。
COPY
- 複制主控端上的檔案到目标鏡像中
文法
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (此格式對于包含空格的路徑是必需的)
規則
同 ADD
ENTRYPOINT
- 類似
指令的功能,用于為容器指定預設運作程式。CMD
- Dockerfile中可以存在多個
指令,但僅最後一個生效ENTRYPOINT
- 與
差別在于,由CMD
啟動的程式不會被ENTRYPOINT
指令行指定的參數所覆寫,而且這些指令行參數會被當做參數傳遞給docker run
指令指定的程式。不過,ENTRYPOINT
的-docker run
選項的參數可覆寫-entrypoint
指定的預設程式ENTRYPOINT
文法
ENTRYPOINT ["executable", "param1", "param2"] (執行表格,首選)
ENTRYPOINT command param1 param2
VOLUME
- 等同于
docker run -v
- 用于在鏡像中建立一個挂載點目錄。在dockerfile中隻支援docker管理的卷,也就是說隻能指定容器内的路徑,不能指定主控端的路徑。主控端可以通過
檢視。docker inspect container
文法
注意事項
- 基于Windows的容器上的卷:使用基于Windows的容器時,容器内的卷的目的地必須是以下之一:
- 不存在或空目錄
- 除以下以外的驅動器 C:
- 從Dockerfile内更改卷:如果在聲明了卷後有任何建構步驟更改了卷内的資料,則這些更改将被丢棄。
- JSON格式:清單被解析為JSON數組。必須用雙引号(")而不是單引号(’)包覆單詞。
- 主機目錄是在容器運作時聲明的:主機目錄(挂載點)從本質上說是依賴于主機的。這是為了保留圖像的可移植性,因為不能保證給定的主機目錄在所有主機上都可用。是以,無法從Dockerfile内挂載主機目錄。該VOLUME指令不支援指定host-dir 參數。建立或運作容器時,必須指定安裝點。
WORKDIR
- 同
docker run -w
- 指定工作目錄,可以指多個,每個
隻影響他下面的指令,直到遇見下一個WORKDIR
為止。WORKDIR
-
也可以調用由ENV指令定義的變量。WORKDIR
文法
WORKDIR /path/to/workdir
- 該WORKDIR指令可以在Dockerfile中多次使用。如果提供了相對路徑,則它将相對于上一條WORKDIR指令的路徑
例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
則最終路徑為/a/b/c
ARG
-
G指令同AR
類似,也是指定一個變量,但不同的是,EVN
指令配合ENV
參數可以在-e
過程中傳參,而使用docker run
指令配合ARG
參數可以在--build-arg
過程中傳參,這友善了我們為不同場景建構不同鏡像。docker build
文法
ONBUILD
- 用于在Dockerfile中定義一個觸發器。
-
後面指定的指令在ONBUILD
時是不會執行,建構完的鏡像在被另一個Dockerfile檔案中FROM指令所引用的時才會觸發執行。docker build
文法
STOPSIGNAL
- 指定發送使容器退出的系統調用信号。
之是以能停止容器,就是發送了15的信号給容器内PID為1的程序。docker stop
文法
STOPSIGNAL signal