一、什么是Dockerfile
Dockerfile是一個包含用于組合映像的命令的文本文檔。可以使用在命令行中調用任何命令。 Docker通過讀取Dockerfile
中的指令自動生成映像。
docker build
命令用于從Dockerfile構建映像。可以在docker build
命令中使用-f
標志指向文件系統中任何位置的Dockerfile。
例:docker build -f /path/to/a/Dockerfile
二、Dockerfile注意事項
- Dockerfile中所用的所有文件應Dockerfile文件在同一級父目錄下,可以為Dockerfile父目錄的子目錄
- 2.Dockerfile中相對路徑默認都是Dockerfile所在的目錄
- 3.Dockerfile中一定要惜字如金,能寫到一行的指令,一定要寫到一行,原因是分層構建,聯合掛載這個特性。Dockerfile中每一條指令被視為一層
- 4.Dockerfile中指明大寫(約定俗成)
三、Dockerfile指令介紹
1、FROM
功能為指定基礎鏡像,并且必須是第一條指令。如果不以任何鏡像為基礎,那么寫法為FROM scratch
。同時意味著接下來所寫的指令將作為鏡像的第一層開始
#語法:
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
#其中<tag>和<digest> 是可選項,默認值為latest
2、MAINTAINER
指定作者(新版docker中使用LABEL指明)
#語法
MAINTAINER <name>
3、LABEL
為鏡像指定標簽(LABEL會繼承基礎鏡像種的LABEL,如遇到key相同,則值覆蓋)
#語法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
#一個Dockerfile種可以有多個LABEL,換行可使用\符號
#如下:
LABEL key1="value1" \
key2="value2" \
key3="value3"
4、ADD
一個復制命令,把文件復制到鏡像中。類似于Linux系統中的scp命令,只是scp需要加用戶名和密碼的權限驗證,而ADD不用。
#語法
ADD file PATH/
#- 路徑的填寫可以是容器內的絕對路徑,也可以是相對于工作目錄的相對路徑,推薦寫成絕對路徑
#- 可以是一個本地文件或者是一個本地壓縮文件,還可以是一個url
#- 如果把寫成一個url,那么ADD就類似于wget命令
5、COPY
復制命令,COPY的只能是本地文件,其他用法與ADD一致
6、EXPOSE
功能為暴漏容器運行時的監聽端口給外部,但是EXPOSE并不會使容器訪問主機的端口,如果想使得容器與主機的端口有映射關系,必須在容器啟動的時候加上 -P參數
#語法
EXPOSE <port>/<tcp/udp>
7、ENV
設置環境變量
#語法有兩種ENV <key> <value>ENV <key>=<value> ...#兩者的區別就是第一種是一次設置一個,第二種是一次設置多個
8、在Dockerfile中使用變量的方式
$varname${varname}${varname:-default value}$(varname:+default value}#第一種和第二種相同#第三種表示當變量不存在使用-號后面的值#第四種表示當變量存在時使用+號后面的值(當然不存在也是使用后面的值)
9、RUN
功能為運行指定的命令
RUN命令有兩種格式
# 語法有兩種
RUN <command>
RUN ["executable", "param1", "param2"]
#第一種后邊直接跟shell命令
#- 在linux操作系統上默認 /bin/sh -c
#- 在windows操作系統上默認 cmd /S /C
#第二種是類似于函數調用。
#- 可將executable理解成為可執行文件,后面就是兩個參數。
10、CMD
功能為容器啟動時默認命令或參數
#語法有三種寫法
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
#第三種比較好理解了,就時shell這種執行方式和寫法
#第一種和第二種其實都是可執行文件加上參數的形式
11、RUN&&CMD
#RUN是構件容器時就運行的命令以及提交運行結果
#CMD是容器啟動時執行的命令,在構件時并不運行,構件時緊緊指定了這個命令到底是個什么樣子
12、ENTRYPOINT
容器啟動時運行得啟動命令
#語法
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
#- 第二種就是寫shell
#- 第一種就是可執行文件加參數
與CMD比較:
相同點:
-
只能寫一條,如果寫了多條,那么只有最后一條生效
-
容器啟動時才運行,運行時機相同
不同點:
- ENTRYPOINT不會被運行的command覆蓋,而CMD則會被覆蓋
- 如果我們在Dockerfile種同時寫了ENTRYPOINT和CMD,并且CMD指令不是一個完整的可執行命令,那么CMD指定的內容將會作為ENTRYPOINT的參數
13、VOLUME
可實現掛載功能,可以將宿主機目錄掛載到容器中,可用專用的文件存儲當作Docker容器的數據存儲部分,一般的使用場景為需要持久化存儲數據時,容器使用的是AUFS,這種文件系統不能持久化數據,當容器關閉后,所有的更改都會丟失。所以當數據需要持久化時用這個命令。
#語法
VOLUME ["/data"]
#["/data"]可以是一個JsonArray ,也可以是多個值。所以如下幾種寫法都是正確的
14、USER
設置啟動容器的用戶,可以是用戶名或UID
# 語法有兩種
USER daemo
USER UID
注意:如果設置了容器以daemon用戶去運行,那么RUN, CMD 和 ENTRYPOINT 都會以這個用戶去運行,使用這個命令一定要確認容器中擁有這個用戶,并且擁有足夠權限
15、WORKDIR
設置工作目錄,對RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在則會創建,也可以設置多次
#語法
WORKDIR /path/to/workdir
16、ARG
設置變量命令,ARG命令定義了一個變量,在docker build創建鏡像的時候,使用 --build-arg =來指定參數
語法
ARG <name>[=<default value>]
如果用戶在build鏡像時指定了一個參數沒有定義在Dockerfile種,那么將有一個Warning
17、ONBUILD
#語法
ONBUILD [INSTRUCTION]
這個命令只對當前鏡像的子鏡像生效。
比如當前鏡像為A,在Dockerfile種添加:
ONBUILD RUN ls -al
這個 ls -al 命令不會在A鏡像構建或啟動的時候執行
此時有一個鏡像B是基于A鏡像構建的,那么這個ls -al 命令會在B鏡像構建的時候被執行。
18、STOPSIGNAL
當容器停止時給系統發送什么樣的指令,默認是15
#語法
STOPSIGNAL signal
19、HEALTHCHECK
容器健康狀況檢查命令
# 語法有兩種
HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE
#第一個的功能是在容器內部運行一個命令來檢查容器的健康狀況
#第二個的功能是在基礎鏡像中取消健康檢查命令
#[OPTIONS]的選項支持以下三中選項:
#- –interval=DURATION 兩次檢查默認的時間間隔為30秒
#- –timeout=DURATION 健康檢查命令運行超時時長,默認30秒
#- –retries=N 當連續失敗指定次數后,則容器被認為是不健康的,狀態為unhealthy,默認次數是3
注意:
HEALTHCHECK命令只能出現一次,如果出現了多次,只有最后一個生效。
CMD后邊的命令的返回值決定了本次健康檢查是否成功,具體的返回值如下:
- 0: success - 表示容器是健康的
- 1: unhealthy - 表示容器已經不能工作了
- 2: reserved - 保留值