Dokcerfile介紹
????Dockerfile是由一系列命令和參數(shù)構(gòu)成的腳本烤宙,這些命令應(yīng)用于基礎(chǔ)鏡像并最終創(chuàng)建一個新的鏡像引颈。它們簡化了從頭到尾的流程并極大的簡化了部署工作。Dockerfile從FROM命令開始雄右,緊接著跟隨者各種方法剃诅,命令和參數(shù)巷送。其產(chǎn)出為一個新的可以用于創(chuàng)建容器的鏡像。
以下就是一些基礎(chǔ)常用的命令語句
FROM
????功能為指定基礎(chǔ)鏡像矛辕,
????并且必須是第一條指令,如果不以任何鏡像為基礎(chǔ)笑跛,那么寫法為:FROM scratch,
????同時意味著接下來所寫的指令將作為鏡像的第一層開始
????語法:
????FROM <image>
????FROM <image>:<tag>
????FROM <image>:<digest>
????三種寫法,其中<tag>和<digest> 是可選項聊品,如果沒有選擇飞蹂,那么默認(rèn)值為latest
RUN
????功能為運行指定的命令
????RUN命令有兩種格式
????RUN <command>
????RUN ["executable", "param1", "param2"]
????第一種后邊直接跟shell命令
????在linux操作系統(tǒng)上默認(rèn) /bin/sh -c
????在windows操作系統(tǒng)上默認(rèn) cmd /S /C
????第二種是類似于函數(shù)調(diào)用。
????可將executable理解成為可執(zhí)行文件翻屈,后面就是兩個參數(shù)陈哑。
????兩種寫法比對:
????????RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME
????????RUN ["/bin/bash", "-c", "echo hello"]
????????注意:多行命令不要寫多個RUN,原因是Dockerfile中每一個指令都會建立一層.
?????????多少個RUN就構(gòu)建了多少層鏡像伸眶,會造成鏡像的臃腫惊窖、多層,不僅僅增加了構(gòu)件部署的時間厘贼,還容易出錯界酒。
????????RUN書寫時的換行符是\
CMD
????功能為容器啟動時要運行的命令
????語法有三種寫法
????????1. CMD ["executable","param1","param2"]
????????2. CMD ["param1","param2"]
????????3. CMD command param1 param2
????第三種比較好理解了,就時shell這種執(zhí)行方式和寫法
????第一種和第二種其實都是可執(zhí)行文件加上參數(shù)的形式
????舉例說明兩種寫法:
????CMD [ "sh", "-c", "echo $HOME"
????CMD [ "echo", "$HOME" ]
????補充細節(jié):這里邊包括參數(shù)的一定要用雙引號涂臣,就是",不能是單引號盾计。千萬不能寫成單引號。
????原因是參數(shù)傳遞后赁遗,docker解析的是一個JSON array
????RUN & CMD
????不要把RUN和CMD搞混了署辉。
????RUN是構(gòu)件容器時就運行的命令以及提交運行結(jié)果
????CMD是容器啟動時執(zhí)行的命令,在構(gòu)件時并不運行岩四,構(gòu)件時緊緊指定了這個命令到底是個什么樣子
LABEL
????功能是為鏡像指定標(biāo)簽
????語法:
????LABEL <key>=<value> <key>=<value> <key>=<value> ...
?????一個Dockerfile種可以有多個LABEL哭尝,如下:
????LABEL "com.example.vendor"="ACME Incorporated"
????LABEL com.example.label-with-value="foo"
????LABEL version="1.0"
????LABEL description="This text illustrates \
????that label-values can span multiple lines."
?????但是并不建議這樣寫,最好就寫成一行剖煌,如太長需要換行的話則使用\符號
????如下:
????????LABEL multi.label1="value1" \
????????multi.label2="value2" \
????????other="value3"
????說明:LABEL會繼承基礎(chǔ)鏡像種的LABEL材鹦,如遇到key相同逝淹,則值覆蓋
MAINTAINER
????指定作者
????語法:
????MAINTAINER <name>
EXPOSE
????功能為暴漏容器運行時的監(jiān)聽端口給外部
????但是EXPOSE并不會使容器訪問主機的端口
????如果想使得容器與主機的端口有映射關(guān)系,必須在容器啟動的時候加上 -P?參數(shù)
ENV
????功能為設(shè)置環(huán)境變量
????語法有兩種
? ??1. ENV <key> <value>
? ??2. ENV <key>=<value> ...
????兩者的區(qū)別就是第一種是一次設(shè)置一個桶唐,第二種是一次設(shè)置多個
ADD
?????一個復(fù)制命令栅葡,把文件復(fù)制到景象中。
????如果把虛擬機與容器想象成兩臺linux服務(wù)器的話尤泽,那么這個命令就類似于scp欣簇,只是scp需要加用戶名和密碼的權(quán)限驗證,而ADD不用坯约。
????語法如下:
? ??1. ADD <src>... <dest>
? ??2. ADD ["<src>",... "<dest>"]
????<dest>路徑的填寫可以是容器內(nèi)的絕對路徑熊咽,也可以是相對于工作目錄的相對路徑
????<src>可以是一個本地文件或者是一個本地壓縮文件,還可以是一個url
????如果把<src>寫成一個url闹丐,那么ADD就類似于wget命令
????盡量不要把<scr>寫成一個文件夾横殴,如果<src>是一個文件夾了,復(fù)制整個目錄的內(nèi)容,包括文件系統(tǒng)元數(shù)據(jù)
COPY
????看這個名字就知道卿拴,又是一個復(fù)制命令
????語法如下:
? ??1. COPY <src>... <dest>
? ??2. COPY ["<src>",... "<dest>"]
????與ADD的區(qū)別
????COPY的<src>只能是本地文件衫仑,其他用法一致
ENTRYPOINT
????功能是啟動時的默認(rèn)命令
????語法如下:
? ??1. ENTRYPOINT ["executable", "param1", "param2"]
? ??2. ENTRYPOINT command param1 param2
????如果從上到下看到這里的話,那么你應(yīng)該對這兩種語法很熟悉啦堕花。
????第二種就是寫shell
????第一種就是可執(zhí)行文件加參數(shù)
????與CMD比較說明(這倆命令太像了惑畴,而且還可以配合使用):
????????1. 相同點:
????????????只能寫一條,如果寫了多條航徙,那么只有最后一條生效
????????????容器啟動時才運行,運行時機相同
????????2. 不同點:
?????????????ENTRYPOINT不會被運行的command覆蓋陷虎,而CMD則會被覆蓋
?????????????如果我們在Dockerfile種同時寫了ENTRYPOINT和CMD到踏,并且CMD指令不是一個完整的可執(zhí)行命令,
????????????????那么CMD指定的內(nèi)容將會作為ENTRYPOINT的參數(shù)
????????Docker中CMD與ENTRYPOINT的簡明理解
VOLUME
????可實現(xiàn)掛載功能尚猿,可以將內(nèi)地文件夾或者其他容器種得文件夾掛在到這個容器種
????語法為:
? ??VOLUME ["/data"]
????說明:
????? ?["/data"]可以是一個JsonArray 窝稿,也可以是多個值。所以如下幾種寫法都是正確的
? ??VOLUME ["/var/log/"]
? ??VOLUME /var/log
? ??VOLUME /var/log /var/db
????一般的使用場景為需要持久化存儲數(shù)據(jù)時
????容器使用的是AUFS凿掂,這種文件系統(tǒng)不能持久化數(shù)據(jù)伴榔,當(dāng)容器關(guān)閉后,所有的更改都會丟失庄萎。
????所以當(dāng)數(shù)據(jù)需要持久化時用這個命令踪少。
USER
????設(shè)置啟動容器的用戶,可以是用戶名或UID糠涛,所以援奢,只有下面的兩種寫法是正確的
? ??USER daemo
? ??USER UID
????注意:如果設(shè)置了容器以daemon用戶去運行,那么RUN, CMD 和 ENTRYPOINT 都會以這個用戶去運行
ARG
????語法:
? ??ARG <name>[=<default value>]
????設(shè)置變量命令忍捡,ARG命令定義了一個變量集漾,在docker build創(chuàng)建鏡像的時候切黔,
????使用 --build-arg <varname>=<value>來指定參數(shù)
????如果用戶在build鏡像時指定了一個參數(shù)沒有定義在Dockerfile種,那么將有一個Warning
????????提示如下:
? ??[Warning] One or more build-args [foo] were not consumed.
????我們可以定義一個或多個參數(shù)具篇,如下:
? ??FROM busybox
? ??ARG user1
? ??ARG buildno
? ??...
????也可以給參數(shù)一個默認(rèn)值:
? ??FROM busybox
? ??ARG user1=someuser
? ??ARG buildno=1
? ??...
????如果我們給了ARG定義的參數(shù)默認(rèn)值纬霞,那么當(dāng)build鏡像時沒有指定參數(shù)值,將會使用這個默認(rèn)值
ONBUILD
????語法:
? ??ONBUILD [INSTRUCTION]
????這個命令只對當(dāng)前鏡像的子鏡像生效驱显。
????比如當(dāng)前鏡像為A诗芜,在Dockerfile種添加:
? ??ONBUILD RUN ls -al
????這個 ls -al 命令不會在A鏡像構(gòu)建或啟動的時候執(zhí)行
? ? 此時有一個鏡像B是基于A鏡像構(gòu)建的,那么這個ls -al 命令會在B鏡像構(gòu)建的時候被執(zhí)行秒紧。
STOPSIGNAL
????語法:
? ??STOPSIGNAL signal
????STOPSIGNAL命令是的作用是當(dāng)容器推出時給系統(tǒng)發(fā)送什么樣的指令