Docker 構(gòu)建腳本 Dockerfile 指令全解析

Dockerfile

1. 前言

Dockerfile 是用來(lái)構(gòu)建自定義 Docker 鏡像的文本文檔暴拄。我們通過(guò)docker build 命令用于從Dockerfile 文件構(gòu)建鏡像榕茧。 如果你要構(gòu)建自定義鏡像,Dockerfile 是你必須學(xué)會(huì)的技能之一。

2. Dockerfile 的基本結(jié)構(gòu)

Dockerfile 一般分為:基礎(chǔ)鏡像、鏡像元信息跟匆、鏡像操作指令和容器啟動(dòng)時(shí)執(zhí)行指令,#Dockerfile 中的注釋通砍。

3. Dockerfile 文件說(shuō)明

Docker 從上到下的順序運(yùn)行Dockerfile 的指令玛臂,每一個(gè)指令都以 step 為步驟。而且文件的命名也必須為 Dockerfile 封孙。

4. Dockerfile 常用的指令迹冤。

接下來(lái)對(duì)常用的 Dockerfile 指令進(jìn)行總結(jié)。

4.1 FROM 指令

FROM是指定基礎(chǔ)鏡像虎忌,必須為第一個(gè)命令泡徙,格式:

FROM <image>:<tag>

其中 tagdigest 是可選的,如果不使用這兩個(gè)值時(shí)膜蠢,會(huì)使用 latest 版本的基礎(chǔ)鏡像堪藐。

示例: FROM mysql:5.6

4.2 MAINTAINER 指令

MAINTAINER 用來(lái)聲明維護(hù)者信息,該命令已經(jīng)過(guò)期,推薦使用 LABEL 挑围,格式:

MAINTAINER <name>

4.3 LABEL 指令

LABEL:用于為鏡像添加元數(shù)據(jù),多用于聲明構(gòu)建信息礁竞,作者、機(jī)構(gòu)杉辙、組織等模捂。格式:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例: LABEL version="1.0" description="felord.cn" by="Felordcn"

使用LABEL 指定元數(shù)據(jù)時(shí),一條LABEL指定可以指定一或多條元數(shù)據(jù)奏瞬,指定多條元數(shù)據(jù)時(shí)不同元數(shù)據(jù)之間通過(guò)空格分隔。推薦將所有的元數(shù)據(jù)通過(guò)一條LABEL指令指定泉孩,以免生成過(guò)多的中間鏡像硼端。

4.4 ENV 指令

ENV 用來(lái)設(shè)置環(huán)境變量,格式:

ENV <key> <value>  

ENV <key>=<value>  

示例: ENV version 1.0.0 或者 ENV version=1.0.0

可以通過(guò) ${key} 在其它指令中來(lái)引用變量寓搬,如 ${version} 珍昨。我們也可以通過(guò) docker run 中的 -e <ENV> 來(lái)動(dòng)態(tài)賦值

4.5 ARG 指令

ARG 用于指定傳遞給構(gòu)建運(yùn)行時(shí)的變量,格式:

ARG <name>[=<default value>]

通過(guò) docker run 中的 --build-arg <key>=<value> 來(lái)動(dòng)態(tài)賦值,不指定將使用其默認(rèn)值镣典。

4.6 WORKDIR 指令

WORKDIR 用來(lái)指定工作目錄兔毙,類似于我們通常使用的cd 命令,格式:

WORKDIR <PATH>

通過(guò) WORKDIR 設(shè)置工作目錄兄春,Dockerfile 中的其它指令 RUN澎剥、CMDENTRYPOINT赶舆、ADD哑姚、COPY等命令都會(huì)在該目錄下執(zhí)行。在使用 docker run 運(yùn)行容器時(shí)芜茵,可以通過(guò) -w 參數(shù)覆蓋構(gòu)建時(shí)所設(shè)置的工作目錄叙量。

4.7 ADD 指令

ADD 用于將本地文件添加到鏡像中,tar 類型文件會(huì)自動(dòng)解壓(網(wǎng)絡(luò)壓縮資源不會(huì)被解壓)九串,可以訪問(wèn)網(wǎng)絡(luò)資源绞佩,類似 wget,格式:

 ADD <src>... <dest>
 # 用于支持包含空格的路徑
 ADD ["<src>",... "<dest>"] 

示例:

ADD home* /path/ # 支持通配符 * 添加所有以"home"開頭的文件 到/path/ 下

4.8 COPY 指令

COPY 的功能類似于 ADD猪钮,但是不會(huì)自動(dòng)解壓文件品山,也不能訪問(wèn)網(wǎng)絡(luò)資源

4.9 RUN 指令

RUN 用來(lái)執(zhí)行構(gòu)建鏡像時(shí)執(zhí)行的命令,有以下兩種命令執(zhí)行方式:

  • shell 執(zhí)行格式:

RUN <command>

示例:RUN apk update

  • exec 執(zhí)行格式:

RUN ["executable", "param1", "param2"]

示例: RUN ["/dev/file", "p1", "p2"]

需要注意的是: RUN 指令創(chuàng)建的中間鏡像會(huì)被緩存躬贡,并會(huì)在下次構(gòu)建中使用谆奥。如果不想使用緩存鏡像,可在構(gòu)建時(shí)指定 --no-cache 參數(shù)拂玻,示例:docker build --no-cache

4.10 CMD 指令

CMD 構(gòu)建容器后執(zhí)行的命令酸些,也就是在容器啟動(dòng)時(shí)才執(zhí)行的命令。格式:

 # 執(zhí)行可執(zhí)行文件檐蚜,優(yōu)先執(zhí)行
 CMD ["executable","param1","param2"]  
 # 設(shè)置了 ENTRYPOINT魄懂,則直接調(diào)用ENTRYPOINT添加參數(shù)  參見 CMD 講解 
 CMD ["param1","param2"] 
 # 執(zhí)行shell命令
 CMD command param1 param2  

示例: CMD ["/usr/bin/bash","--help"]

CMD 不同于 RUNCMD 用于指定在容器啟動(dòng)時(shí)所要執(zhí)行的命令闯第,而RUN用于指定鏡像構(gòu)建時(shí)所要執(zhí)行的命令市栗。

4.11 ENTRYPOINT 指令

ENTRYPOINT 用來(lái)配置容器,使其可執(zhí)行化咳短。配合 CMD可省去 application填帽,只使用參數(shù)。格式:

 #可執(zhí)行文件, 優(yōu)先
 ENTRYPOINT ["executable", "param1", "param2"]  
 # shell內(nèi)部命令
 ENTRYPOINT command param1 param2  

示例:

    FROM ubuntu

    ENTRYPOINT ["top", "-b"]

    CMD ["-c"] 

ENTRYPOINTCMD 非常類似咙好,不同的是通過(guò) docker run 執(zhí)行的命令不會(huì)覆蓋 ENTRYPOINT 篡腌,而 docker run 命令中指定的任何參數(shù)都會(huì)被當(dāng)做參數(shù)再次傳遞給 ENTRYPOINT 指令。Dockerfile 中只有最后一個(gè) ENTRYPOINT 命令起作用勾效,也就是說(shuō)如果你指定多個(gè)ENTRYPOINT,只執(zhí)行最后的 ENTRYPOINT 指令嘹悼。

4.12 EXPOSE 指令

EXPOSE 指定與外界交互的端口叛甫,格式:

EXPOSE [<port>...]

示例: EXPOSE 8080 443EXPOSE 80 杨伙、EXPOSE 11431/tcp 12551/udp

EXPOSE 并不會(huì)直接讓容器的端口映射主機(jī)其监。宿主機(jī)訪問(wèn)容器端口時(shí),需要在 docker run 運(yùn)行容器時(shí)通過(guò) -p 來(lái)發(fā)布這些端口限匣,或通過(guò) -P 參數(shù)來(lái)發(fā)布EXPOSE 導(dǎo)出的所有端口

4.13 VOLUME 指令

VOLUME 用于指定持久化目錄, 格式:

VOLUME ["<src>",...]

示例:VOLUME ["/data"]抖苦,VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

一個(gè)卷可以存在于一個(gè)或多個(gè)容器的指定目錄,該目錄可以繞過(guò)聯(lián)合文件系統(tǒng)膛腐,并具有以下功能:

  1. 卷可以容器間共享和重用
  2. 容器并不需要要和其它容器共享卷
  3. 修改卷后會(huì)立即生效
  4. 對(duì)卷的修改不會(huì)對(duì)鏡像產(chǎn)生影響
  5. 卷會(huì)一直存在睛约,直到?jīng)]有任何容器在使用它

EXPOSE 指令類似, VOLUME 并不會(huì)掛載的宿主機(jī)哲身,需要通過(guò) docker run 運(yùn)行容器時(shí)通過(guò) -v 來(lái)映射到宿主機(jī)的目錄中辩涝。參見另一個(gè)命令 docker volume create

4.14 USER 指令

USER 指定運(yùn)行容器時(shí)的用戶名或 UID,后續(xù)的 RUN 也會(huì)使用指定用戶勘天。使用 USER 指定用戶時(shí)怔揩,可以使用用戶名、UIDGID脯丝,或是兩者的組合商膊。當(dāng)服務(wù)不需要管理員權(quán)限時(shí),可以通過(guò)該命令指定運(yùn)行用戶宠进。并且可以在之前創(chuàng)建所需要的用戶,格式:

USER user
USER user:group
USER uid:group
USER uid
USER user:gid
USER uid:gid

使用 USER 指定用戶后晕拆,Dockerfile 中其后的命令 RUNCMD材蹬、ENTRYPOINT 都將使用該用戶实幕。你可以通過(guò) docker run 運(yùn)行容器時(shí),可以通過(guò) -u 參數(shù)來(lái)覆蓋指定用戶堤器。

4.15 ONBUILD 指令

ONBUILD 作用是其當(dāng)所構(gòu)建的鏡像被用做其它鏡像的基礎(chǔ)鏡像昆庇,該鏡像中的 ONBUILD 中的命令就會(huì)觸發(fā),格式:

ONBUILD [INSTRUCTION]

示例:

ONBUILD ADD . /application/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src 

5. 總結(jié)

今天對(duì)構(gòu)建 Docker 鏡像腳本 Dockerfile 基本命令進(jìn)行的詳細(xì)的總結(jié)闸溃,并加以舉例說(shuō)明整吆,相信能解決你在構(gòu)建鏡像中的一些困惑。敬請(qǐng)多多關(guān)注微信公眾號(hào):Felordcn 辉川,后續(xù)將會(huì)有更多干貨奉上表蝙。

附: Spring Boot Dockerfile

   # 使用 aws 的java jdk 8
   FROM amazoncorretto:8
   # 作者等相關(guān)的元信息
   LABEL AUTHOR=Felordcn OG=felord.cn
   # 掛載卷 
   VOLUME ["/tmp","/logs"]
   # 時(shí)區(qū)
   ENV TZ=Asia/Shanghai
   # 啟用配置文件 默認(rèn)為 application.yml  
   ENV ACTIVE=defualt
   # 設(shè)置鏡像時(shí)區(qū)
   RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
   # 修改為打包后的jar文件名稱
   ADD /target/flyway-spring-boot-1.0.0.jar app.jar
   ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=${ACTIVE}","-jar","app.jar"]

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市乓旗,隨后出現(xiàn)的幾起案子府蛇,更是在濱河造成了極大的恐慌,老刑警劉巖寸齐,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欲诺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡渺鹦,警方通過(guò)查閱死者的電腦和手機(jī)扰法,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)毅厚,“玉大人塞颁,你說(shuō)我怎么就攤上這事∥ⅲ” “怎么了祠锣?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)咽安。 經(jīng)常有香客問(wèn)我伴网,道長(zhǎng),這世上最難降的妖魔是什么妆棒? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任澡腾,我火速辦了婚禮,結(jié)果婚禮上糕珊,老公的妹妹穿的比我還像新娘动分。我一直安慰自己,他們只是感情好红选,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布澜公。 她就那樣靜靜地躺著,像睡著了一般喇肋。 火紅的嫁衣襯著肌膚如雪坟乾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天苟蹈,我揣著相機(jī)與錄音糊渊,去河邊找鬼。 笑死慧脱,一個(gè)胖子當(dāng)著我的面吹牛渺绒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播菱鸥,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宗兼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了氮采?” 一聲冷哼從身側(cè)響起殷绍,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹊漠,沒(méi)想到半個(gè)月后主到,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茶行,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年登钥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畔师。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牧牢,死狀恐怖看锉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情塔鳍,我是刑警寧澤伯铣,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站轮纫,受9級(jí)特大地震影響腔寡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掌唾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一蹬蚁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧郑兴,春花似錦犀斋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至却舀,卻和暖如春虫几,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挽拔。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工辆脸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人螃诅。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓啡氢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親术裸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子倘是,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354