格式
- 所有的指令是非大小寫敏感的,但習(xí)慣寫為大寫有助于與你的參數(shù)做區(qū)分
- 所有的指令按照Dockerfile文件順序執(zhí)行
- 一個(gè)Dockerfile必須以FROM指令開始(但可以在解析器指令
parse derictive
、注釋comments
或全局參數(shù)ARGs
后) - FROM前可以有一個(gè)或多個(gè)ARG,這些ARG中聲明的變量將會(huì)在FROM行中使用
- 與shell,python等腳本語言類似Dockerfile中以#開頭的行會(huì)被當(dāng)做注釋,如果它出現(xiàn)在Dockerfile文件的最上方并且是合法的解析器指令探越。它將會(huì)當(dāng)作解析器處理萌业,同一個(gè)解析器只會(huì)處理一次侧蘸,第二次聲明也將會(huì)當(dāng)作注釋處理。(合法的解析器包括syntax和escape)
.dockerignore
構(gòu)建docker鏡像時(shí)有上下文概念偎捎,例如以docker build -t 鏡像名 .
命令構(gòu)建鏡像是上下文即為Dockerfile所在目錄(當(dāng)然執(zhí)行該命令的工作目錄也在Dockerfile所在目錄)蠢终。
docker 構(gòu)建鏡像時(shí)會(huì)將上下文中的所有文件拷貝到docker的構(gòu)建進(jìn)程中,就像.gitignore一樣聲明在.dockerignore中的文件或文件夾在拷貝時(shí)會(huì)被忽略鸭限。
構(gòu)建指令
-
FROM
所有Dockerfile最先執(zhí)行的指令(當(dāng)然最先是在排除前文提到的解析器指令和參數(shù)等的前提下蜕径,因?yàn)檫@幾個(gè)指令都是可選的)
該指令指定一個(gè)基礎(chǔ)鏡像(也可以理解為父鏡像)两踏。為之后一系列操作提供基礎(chǔ)運(yùn)行環(huán)境败京。
該指令可以使用已定義過的ARG,使用方式為${參數(shù)名},與shell很想對嗎梦染?沒錯(cuò)之后還會(huì)有很多相似之處赡麦。 -
RUN
RUN指令用于在構(gòu)建容器時(shí)執(zhí)行你指定的任意命令。
RUN指令有兩種格式
shell格式
RUN /bin/bash -c 'source \$HOME/.bashrc; \
echo $HOME'
改格式下你可以使用 \ 來在另一行編寫你未完成的單個(gè)命令帕识,并且可以使用${}操作符泛粹,json格式則不可以。
exec格式
RUN ["/bin/bash", "-c", "echo hello"]
exec格式會(huì)被轉(zhuǎn)換為一個(gè)json數(shù)組肮疗,所以你因該使用雙引號"
來包裹你額單詞而不是單引號'
,另外在該格式中應(yīng)避免反斜杠 \
尤其是在windows中\
標(biāo)識了windows的文件目錄晶姊。
-
CMD
一個(gè)Dockerfile中只能有一個(gè)CMD
命令,如果寫了多個(gè)那么只有最后一個(gè)生效伪货。它的目的是為容器提供一個(gè)默認(rèn)執(zhí)行應(yīng)用们衙。
該命令會(huì)被命令行參數(shù)所替換例如如果啟動(dòng)時(shí)執(zhí)行命令為docker run -it 容器名 /bin/sh
則CMD內(nèi)容將被替換為/bin/sh
CMD命令一共有三種格式
exec格式
CMD ["executable","param1","param2"]
該格式是最推薦使用的格式
作為ENTRYPOINT的默認(rèn)參數(shù)
CMD ["param1","param2"]
當(dāng)它作為ENTRYPOINT的參數(shù)的時(shí)候ENTRYPOINT和CMD都必須是json數(shù)組的格式。
shell格式
CMD command param1 param2
使用改格式默認(rèn)會(huì)在/bin/sh -c
中執(zhí)行碱呼,如果不想使用/bin/sh -c
執(zhí)行命令請使用exec格式
-
LABLE
LABLE為構(gòu)建的鏡像添加一些key-value格式的元數(shù)據(jù)蒙挑,和RUN一樣可以使用反斜杠\
在下一行完成單條過長的元數(shù)據(jù)。
例:
FROM ubuntu:18.04
WORKDIR /usr/local
LABEL wxm="wxm530" \
alming="alming530"
構(gòu)建完成后 docker inspect 鏡像名
"WorkingDir": "/usr/local",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"alming": "alming530",
"wxm": "wxm530"
}
LABLE包包括前鏡像和父鏡像的LABLE,如果重復(fù)了以最新的為準(zhǔn).
-
EXPOSE
EXPOSE指定Docker容器運(yùn)行時(shí)向外暴露的端口愚臀,可以指定TCP或UDP協(xié)議端口忆蚀,默認(rèn)采用TCP協(xié)議。指令格式EXPOSE 80/tcp EXPOSE 80/udp
-
ENV
ENV即環(huán)境變量,它有兩種格式
ENV <key> <value>
該格式設(shè)置一個(gè)單個(gè)的環(huán)境變量馋袜,第一個(gè)完整的字符串是key key+空格后的所有值都是value男旗,
它會(huì)被其他環(huán)境變量所解析,如果沒有轉(zhuǎn)義不應(yīng)該在改格式中寫引號"
桃焕。(這里不理解剑肯,只是翻譯了一下官方文檔)
ENV <key>=<value> ...
改格式允許在一行定義多個(gè)環(huán)境變量,以空格分隔观堂。如果環(huán)境變量本身需要空格將有空格的變量使用引號"
括起來或使用\
來轉(zhuǎn)義空格让网。
注意ENV
添加的環(huán)境變量對于容器來說是持久的。如果需要臨時(shí)的變量則使用RUN <key>=<value> <command>.
ADD
- ADD指令用于將主機(jī)或者某個(gè)url上的文件資源拷貝到將要構(gòu)建的鏡像當(dāng)中师痕。
- 源文件地址可以使用
Go’s filepath.Match rules.
解析規(guī)則的通配符溃睹。 - 目的地址是目標(biāo)容器的絕對地址或者是
WORKDIR
的相對地址(關(guān)于WORKDIR
參照WORKDIR
文檔)。 - 如果源地址中包含特殊字符則需要按照Go語言的轉(zhuǎn)義規(guī)則將它們轉(zhuǎn)義胰坟。
- 添加到容器中的文件默認(rèn)由GID和UID為0的用戶創(chuàng)建因篇,如果想改變使用
--chown
參數(shù),這一部分詳細(xì)參照官方文檔。 - 如果添加的文件是歸檔文件還會(huì)被默認(rèn)加壓笔横。
該指令有兩種格式竞滓。
ADD [--chown=<user>:<group>] <src>... <dest>
-
COPY
COPY指令與ADD基本一致,但它不會(huì)解壓添加到容器中的歸檔文件 -
ENTRYPOINT
ENTRYPOINT和CMD類似都用于指定容器啟動(dòng)時(shí)容器內(nèi)執(zhí)行的命令或執(zhí)行可執(zhí)行文件吹缔,CMD中的指令最終都會(huì)以參數(shù)的形式傳遞給ENTRYPOINT(前提是ENTRYPOINT是exec格式)商佑。
ENTRYPOINT有兩種格式
shell格式
ENTRYPOINT command param1 param2
改格式不會(huì)接收CMD作為參數(shù),但有一個(gè)缺點(diǎn)就是使用docker stop
命令無法正常關(guān)閉容器內(nèi)正在運(yùn)行的應(yīng)用,(個(gè)人理解為對于容器中運(yùn)行的應(yīng)用來說容器停止時(shí)它們都是強(qiáng)制退出的厢塘,也就是說如果程序中有結(jié)束程序的鉤子函數(shù)可能無法被正常執(zhí)行)
所以使用改格式時(shí)需要在命令前添加exec例如ENTRYPOINT exec top -b
exec格式
ENTRYPOINT ["executable", "param1", "param2"]
該格式下每個(gè)參數(shù)都是一個(gè)字符不能連寫例如有兩個(gè)參數(shù)-c
和-t
則不能寫成["command","-c -t" ]
因該寫成["command","-c","-c"]
并且所有參數(shù)都要使用雙引號""
茶没,所有寫在CMD中的命令將會(huì)自動(dòng)添加在數(shù)組的尾部作為參數(shù),同時(shí)CMD內(nèi)容可被啟動(dòng)時(shí)命令行內(nèi)容替換晚碾,所以可以使用命令行替換CMD內(nèi)容繼而追加道ENTRYPOINT中抓半。
例:
//Dockerfile
FROM ubuntu:18.04
WORKDIR /usr/local
ENTRYPOINT ["echo"]
CMD wxm
執(zhí)行docker build -t wxm .
構(gòu)建鏡像
先不加參數(shù)運(yùn)行docker run -it wxm
運(yùn)行結(jié)果
[alming@localhost docker]$ docker run -it wxm
/bin/sh -c wxm
[alming@localhost docker]$
可以看到wxm被打印說明CMD中內(nèi)容確實(shí)被追加到ENTRYPOINT中了,同時(shí)看到還打印了/bin/sh -c側(cè)面說明了CMD中命令默認(rèn)由/bin/sh -c
執(zhí)行格嘁,這一點(diǎn)官方文檔中也有提及
接下來運(yùn)行容器時(shí)指定自定義參數(shù)
docker run -it wxm alming
[alming@localhost docker]$ docker run -it wxm alming
alming
[alming@localhost docker]$
可以看到參數(shù)被正確替換并傳遞笛求。
另外如果要為容器中的可執(zhí)行文件編寫可執(zhí)行腳本以在ENTRYPOINT中執(zhí)行需要注意使用exec加gosu啟動(dòng)可執(zhí)行文件這樣可以保證啟動(dòng)的進(jìn)程的PID為1從而可以接收到docker stop
傳過來的停止信號從而優(yōu)雅的結(jié)束該進(jìn)程。目的也是為了保證程序退出前的準(zhǔn)備工作正常完成糕簿。
下面是官方示例:
#!/usr/bin/env bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
-
VOLUME
在容器中創(chuàng)建你聲明的掛載點(diǎn)探入,即創(chuàng)建一個(gè)目錄。并且會(huì)默認(rèn)關(guān)聯(lián)到宿主機(jī)/var/lib/docker/volume下的一個(gè)文件夾下的_data文件夾冶伞。該文件夾由docker生成名稱是一個(gè)hash碼
[root@192 volumes]# pwd
/var/lib/docker/volumes
[root@192 volumes]# ls
0a31112d023a994c3dc4ed945a75fa4c55ce9d94ff80c200d2574bb0270df3d3
0f61fd7fdf69653ab4d5dc6c576b5e809553c83914c8c295bfc3511c56ac50eb
10b2add0f578d26f79fc9ac69df126ab93793314d98ebe37c93e97aa545486bf
17c764a4a52320ce2a85ec7ccab81c6b3845e53225bfc955d3308dc09ead7618
和手使用-v指定的文件夾一樣和容器內(nèi)的文件夾內(nèi)容同步新症。
其值可以是純字符轉(zhuǎn)也可以是json數(shù)組
-
USER
USER指令用來設(shè)置用戶名(或UID)組名(或GID)。設(shè)置完成后响禽,接下來的RUN
,ENTRYPOINT
,CMD
中所執(zhí)行的命令都有該用戶完成徒爹。
格式
USER <UID>[:<GID>]
or
USER <user>[:<group>]
-
WORKDIR
WORKDIR指令為RUN
,CMD
,ENTRYPOINT
,ADD
,COPY
指定工作空間
格式
WORKDIR /path/to/workdir
它可以定義多次并且每次都會(huì)以上一個(gè)WORKDIR指令為相對目錄荚醒,官方示例為
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
最終打印結(jié)果為/a/b/c
WORKDIR 還可以解析之前定義過的ENV中的內(nèi)容,但注意只能解析Dockerfile中定義的ENV系統(tǒng)環(huán)境變量是取不到的隆嗅,官方示例:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
最總打印結(jié)果為/path/$DIRNAME
-
ARG
用戶在使用docker build指令時(shí)可通過--build-arg <varname>=<value>
將參數(shù)傳遞給Dockerfile中聲明的ARG中以供之后通過$參數(shù)名
使用界阁。
同時(shí)它可以有默認(rèn)值ARG user1=someuser
,并且其他指令只能調(diào)用在它本身之前聲明過的ARG。
注意如果ENV定義的變量名和ARG重復(fù)了ENV的值將會(huì)覆蓋ARG的值
Docker中有一些預(yù)定義的ARG這些ARG不需要你聲明也可以使用包括
- HTTP_PROXY
- http_proxy
- HTTPS_PROXY
- https_proxy
- FTP_PROXY
- ftp_proxy
- NO_PROXY
- no_proxy
這些預(yù)定義變量將不會(huì)被docker history輸出
-
ONBUILD
ONBUILD指定當(dāng)子鏡像被構(gòu)建時(shí)需要執(zhí)行的指令胖喳,其中聲明的指令將會(huì)被插入到子鏡像的FROM指令之后執(zhí)行泡躯。
注意,ONBUILD不可嵌套使用并且不會(huì)觸發(fā)FROM指令丽焊。 -
STOPSIGNAL
STOPSIGNAL指定使用docker stop停止容器時(shí)容器內(nèi)應(yīng)用程序的終止行為较剃,格式為
STOPSIGNAL signal
以下內(nèi)容出自stackoverflow非官方文檔,文檔未對此指令做細(xì)致解釋技健。原文
可選取值為
SIGKILL
,SIGTERM
,SIGINT
其中SIGTERM
和SIGINT
可以正常關(guān)閉正在運(yùn)行的應(yīng)用写穴,SIGKILL
則不能
SIGKILL
相當(dāng)于kill -9 <PID>
SIGTERM
相當(dāng)于kill <PID>
SIGINT
相當(dāng)于Ctrl + c
即
-
HEALTHCHECK
HEALTHCHECK目的是在容器中運(yùn)行特定的指令以檢查容器中的應(yīng)用設(shè)否正常工作,他也有兩種格式:
HEALTHCHECK [OPTIONS] CMD command
HEALTHCHECK NONE
繼承自父鏡像雌贱,默認(rèn)不進(jìn)行任何檢測
例如以下指令規(guī)定每5分鐘像web服務(wù)器發(fā)送請求并判斷是否在3s內(nèi)返回從而判斷web服務(wù)器是否正常工作啊送。
-
SHELL
SHELL指令用于切換RUN
,CMD
,ENTRYPOINT
的默認(rèn)shell,默認(rèn)情況下linux使用的是["/bin/sh", "-c"]
Windows使用的是["cmd", "/S", "/C"]
通常用于當(dāng)默認(rèn)shell執(zhí)行不了某個(gè)命令時(shí)使用SHELL
指令切換shell執(zhí)行完成后再通過SHELL
指令切回原來的shell.