DOCKERFILE参数注解
| Dockerfile由一行行命令語(yǔ)句組成,并且支持以#開(kāi)頭的注釋行。 一般的,Dockerfile 分為四部分:基礎(chǔ)鏡像信息、維護(hù)者信息、鏡像操作指令和容器啟動(dòng)時(shí)執(zhí)行指令。 Dockerfile的指令是忽略大小寫(xiě)的,建議使用大寫(xiě),使用 # 作為注釋,每一行只支持一條指令,每條指令可以攜帶多個(gè)參數(shù)。 Dockerfile的指令根據(jù)作用可以分為兩種:構(gòu)建指令和設(shè)置指令。 ? 構(gòu)建指令用于構(gòu)建image,其指定的操作不會(huì)在運(yùn)行image的容器上執(zhí)行; 可以在目錄下創(chuàng)建.dockerignore文件,讓Docker忽略路徑下的文件和目錄。 DockerFile的每一個(gè)指令都會(huì)新構(gòu)建一層。 UnionFS是有最大層數(shù)限制的,比如AUFS,曾經(jīng)是最大不能超過(guò)42層,現(xiàn)在是最大不能超過(guò)127層。所以,對(duì)于一些編譯、軟件的安裝、更新等操作,無(wú)需分成好幾層來(lái)操作,這樣會(huì)使得鏡像非常臃腫,擁有非常多的層,不僅僅增加了構(gòu)建部署的時(shí)間,也很容易出錯(cuò)!! | ||
| 指令 | 描述 | 格式 |
| from | 構(gòu)建指令。 指定基礎(chǔ)鏡像,它是最重要的一個(gè)且必須為dokefile文件開(kāi)篇的第一個(gè)非注釋行,用于為鏡像文件構(gòu)建過(guò)程中指定基礎(chǔ)鏡像,后續(xù)的指令運(yùn)行于此基準(zhǔn)鏡像所提供的運(yùn)行環(huán)境 默認(rèn),docke會(huì)在本機(jī)尋找指定的鏡像,找不到的時(shí)候則從docke hub registery拉取所需鏡像,如果會(huì)找不到,則報(bào)錯(cuò)返回報(bào)錯(cuò)信息 如果在同一個(gè)Dockerfile中創(chuàng)建多個(gè)鏡像時(shí),可以使用多個(gè) FROM 指令。 DockerFile還存在一個(gè)特殊的鏡像srcatch,這個(gè)鏡像是一個(gè)虛擬的概念,并不實(shí)際存在,它表示一個(gè)空白的鏡像。 如果你以scratch作為基礎(chǔ)鏡像,意味著你將不使用任何鏡像為基礎(chǔ),接下來(lái)你所寫(xiě)的指令將作為第一層開(kāi)始存在。不以任何系統(tǒng)為基礎(chǔ),直接將可執(zhí)行文件復(fù)制進(jìn)鏡像的做法并不罕見(jiàn)。如swarm、coreos/etcd。對(duì)Linux下靜態(tài)編譯的程序來(lái)說(shuō),并不需要其他操作提供其運(yùn)行時(shí)支持,所需的一切庫(kù)都在可執(zhí)行文件里了,因此使用scratch作為基礎(chǔ),可以使鏡像的體積更加小巧 | from? <repository>[:<tag>]或者 from <repository>@<digest> repository為基礎(chǔ)鏡像名稱? ?tag為鏡像標(biāo)簽為可選項(xiàng),省略時(shí)為latest該image的最后修改的版本 |
| MAINTAINER | 構(gòu)建指令 用于為docke提供作者信息,無(wú)順序限制 用于將image的制作者相關(guān)的信息寫(xiě)入到image中。當(dāng)我們對(duì)該image執(zhí)行docker inspect命令時(shí),輸出中有相應(yīng)的字段記錄該信息。 此命令已經(jīng)過(guò)時(shí),可以使用LABEL maintainer=xxx 來(lái)替代,定義多個(gè)LABEL時(shí),可以使用 【\】反劃線來(lái)跨行 | |
| copy | 用于從docker主機(jī)復(fù)制文件至創(chuàng)建的新鏡像文件,但不會(huì)自動(dòng)解壓,不能從【 遠(yuǎn)端URL 】 復(fù)制。 目標(biāo)路徑是容器內(nèi)的絕對(duì)路徑,也可以是工作目錄下的相對(duì)路徑,工作目錄可以使用WORKDIR指令進(jìn)行指定。 使用COPY指令會(huì)將源路徑的文件的所有元數(shù)據(jù)都拷貝,比如讀、寫(xiě)、指定全選、時(shí)間變更等。 <源路徑> 可以是多個(gè),甚至可以是通配符,其通配符規(guī)則要滿足 Go 的 filepath.Match 規(guī)則 目標(biāo)路徑不需要事先創(chuàng)建,如果目錄不存在會(huì)在復(fù)制文件前先行創(chuàng)建缺失目錄 在使用該指令的時(shí)候還可以加上 --chown=<user>:<group> 選項(xiàng)來(lái)改變文件的所屬用戶及所屬組。 文件復(fù)制準(zhǔn)則: | 1 COPY [--chown=<user>:<group>] <源路徑>... <目標(biāo)路徑> 2 COPY [--chown=<user>:<group>] ["<源路徑1>",... "<目標(biāo)路徑>"] |
| add | 構(gòu)建指令 ADD指令和COPY的格式和性質(zhì)基本一致,只不過(guò)是在COPY的基礎(chǔ)上增加了一些功能。 如果是一個(gè)目錄,那么會(huì)將該目錄下的所有文件添加到container中,不包括目錄; 如果<src>是文件且<dest>中不使用斜杠結(jié)束,則會(huì)將<dest>視為文件,<src>的內(nèi)容會(huì)寫(xiě)入<dest>; 如果<src>是文件且<dest>中使用斜杠結(jié)束,則會(huì)<src>文件拷貝到<dest>目錄下。 目標(biāo)路徑為一個(gè)URL時(shí),會(huì)將其自動(dòng)下載到目標(biāo)路徑下,但是其權(quán)限被自動(dòng)設(shè)置成了600,如果這并不是你想要的權(quán)限,那么你還需要額外增加一層RUN命令進(jìn)行更改,另外,如果下載的是一個(gè)壓縮包,同樣你還需要額外增加一層RUN命令進(jìn)行解壓縮。所以,在這種情況下,你還不如指定只用一層RUN,使用curl或者wget工具進(jìn)行下載,并更改權(quán)限,然后進(jìn)行解壓縮,最后清理無(wú)用文件! 當(dāng)你的源路徑為壓縮文件并且不想讓Docker引擎將其自動(dòng)解壓縮,這個(gè)時(shí)候就不可以使用ADD命令,你可以使用COPY命令進(jìn)行完成 | |
| run | 構(gòu)建指令。 每條?RUN?指令將在當(dāng)前鏡像基礎(chǔ)上執(zhí)行指定命令,并提交為新的鏡像。當(dāng)命令較長(zhǎng)時(shí)可以使用?\?來(lái)?yè)Q行 RUN可以運(yùn)行任何被基礎(chǔ)image支持的命令。如基礎(chǔ)image選擇了ubuntu,那么軟件管理部分只能使用ubuntu的命令 | shell格式RUN <command>?或 exec格式RUN ["executable", "param1", "param2"] 前者將在 shell 終端中運(yùn)行命令,即?/bin/sh -c;后者則使用?exec?執(zhí)行。指定使用其它終端可以通過(guò)第二種方式實(shí)現(xiàn),例如?RUN ["/bin/bash", "-c", "echo hello"]。 |
| volume | 設(shè)置指令 用于構(gòu)建鏡像時(shí)定義匿名卷。 容器存儲(chǔ)層應(yīng)該保持無(wú)狀態(tài)化,容器運(yùn)行時(shí)應(yīng)盡量保持容器內(nèi)不發(fā)生任何寫(xiě)入操作,對(duì)于需要保存動(dòng)態(tài)數(shù)據(jù)的應(yīng)用,其數(shù)據(jù)文件應(yīng)該將其保存在數(shù)據(jù)卷中。 容器匿名卷目錄指定可以通過(guò)docker run命令中指定-v參數(shù)來(lái)進(jìn)行覆蓋。 如果掛載點(diǎn)目錄下此前存在文件,docker run命令會(huì)在卷掛載完成之后將此前的所有文件復(fù)制到新掛載的卷中 運(yùn)行通過(guò)該Dockerfile生成image的容器,/tmp/data目錄中的數(shù)據(jù)在容器關(guān)閉后,里面的數(shù)據(jù)還存在。 例如另一個(gè)容器也有持久化數(shù)據(jù)的需求,且想使用上面容器共享的/tmp/data目錄,那么可以運(yùn)行下面的命令啟動(dòng)一個(gè)容器: docker run -t -i -rm?-volumes-from container1 image2bash 其中:container1為第一個(gè)容器的ID,image2為第二個(gè)容器運(yùn)行image的名字。 |
|
| expose | 設(shè)置指令 EXPOSE指令是聲明運(yùn)行時(shí)容器服務(wù)端口,這只是一個(gè)聲明,在運(yùn)行時(shí)并不會(huì)因?yàn)檫@個(gè)聲明應(yīng)用就會(huì)開(kāi)啟這個(gè)端口的服務(wù)。 在Dockerfile中這樣聲明有兩個(gè)好處:一個(gè)是幫助鏡像使用者更好的理解這個(gè)鏡像服務(wù)的守護(hù)端口,另一個(gè)作用則是在運(yùn)行時(shí)使用隨機(jī)端口映射時(shí),也就是docker run -p命令時(shí),會(huì)自動(dòng)隨機(jī)映射EXPOSE端口。 要將EXPOSE和在運(yùn)行時(shí)使用-p <宿主>:<容器端口>區(qū)分開(kāi)來(lái),-p是映射宿主端口和容器端口,換句話說(shuō),就是將容器的對(duì)應(yīng)端口服務(wù)公開(kāi)給外界訪問(wèn),而EXPOSE僅僅是聲明端口使用什么端口而已,并不會(huì)自動(dòng)在宿主進(jìn)行端口映射 EXPOSE指令可以一次設(shè)置多個(gè)端口號(hào),相應(yīng)的運(yùn)行容器的時(shí)候,可以配套的多次使用-p選項(xiàng)。 | EXPOSE 端口號(hào) EXPOSE 端口號(hào)/協(xié)議 默認(rèn)協(xié)議為T(mén)CP |
| env | 設(shè)置指令 指定環(huán)境變量,它可以被其后的add、copy等調(diào)用 可以通過(guò)docker inspect查看這個(gè)環(huán)境變量,也可以通過(guò)在docker run --env?key=value時(shí)設(shè)置或修改環(huán)境變量 如果你要設(shè)置多個(gè)環(huán)境變量,為了美觀,你可以使用\來(lái)進(jìn)行換行。多個(gè)環(huán)境變量的隔開(kāi),使用空格進(jìn)行隔開(kāi)的,如果某個(gè)環(huán)境變量的值是由一組英文單詞構(gòu)成,那么你可以將其使用""進(jìn)行圈起來(lái) 值得注意的是,如果你想通過(guò)CMD或者ENTRYPOINT指令的exec格式來(lái)打印環(huán)境 CMD ["echo", $MODE] CMD ["echo", "$MODE"] 上面這樣都是不能正確輸出環(huán)境變量的值的,你可以改成exec格式來(lái)執(zhí)行shell命令,如下 CMD ["sh", "-c", "echo $MODE"] | 調(diào)用格式$name或者${name} |
| wokrdir | 設(shè)置指令 使用WORKDIR指令來(lái)制定工作目錄(或者稱為當(dāng)前目錄),以后各層操作的當(dāng)前目錄就是為指定的目錄,如果該目錄不存在,WORKDIR會(huì)自動(dòng)幫你創(chuàng)建目錄 WORKDIR指令可以通過(guò)docker run命令中的-w參數(shù)來(lái)進(jìn)行覆蓋 | |
| user | 設(shè)置指令 指令用于將會(huì)用以什么樣的用戶去運(yùn)行默認(rèn)為root 可以指定用戶名或者UID,組名或者GID,或者兩者的結(jié)合 USER指令可以在docker run命令中的-u參數(shù)進(jìn)行覆蓋 后續(xù)的?RUN?也會(huì)使用指定用戶。 當(dāng)服務(wù)不需要管理員權(quán)限時(shí),可以通過(guò)該命令指定運(yùn)行用戶。并且可以在之前創(chuàng)建所需要的用戶,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要臨時(shí)獲取管理員權(quán)限可以使用?gosu,而不推薦?sudo | |
| healthcheck | 告訴Docker該如何判斷容器的狀態(tài)是否正常,這是1.12引入的新指令 在沒(méi)有HEALTHCHECK指令之前,Docker引擎只可以通過(guò)容器內(nèi)主進(jìn)程是否退出來(lái)判斷容器狀態(tài)是否異常。很多情況下這沒(méi)有問(wèn)題,但是如果程序進(jìn)入了死鎖狀態(tài),或者死循環(huán)狀態(tài),應(yīng)用進(jìn)程并不退出,但是該容器已經(jīng)無(wú)法繼續(xù)提供服務(wù)了。在1.12之前,Docker引擎不會(huì)檢測(cè)到容器的這種狀態(tài),從而不會(huì)重新調(diào)度,導(dǎo)致可能容器已經(jīng)無(wú)法提供服務(wù)了卻仍然還在接收用戶的請(qǐng)求。 HEALTHCHECK指令只可以出現(xiàn)一次,如果有多個(gè)HEALTHCHECK指令,那么只有最后一個(gè)才會(huì)生效 | HEALTHCHECK [options] CMD <命令>:檢查容器健康狀態(tài)的命令 HEALTHCHECK NONE:如果基礎(chǔ)鏡像有健康檢查指令,這一行將會(huì)屏蔽掉其健康檢查指令 HEALTHECHECK支持下列選項(xiàng): ? ? ?–interval=<間隔>:兩次檢查的時(shí)間間隔,默認(rèn)為30s ? ? ?–timeout=<時(shí)長(zhǎng)>:健康檢查命令運(yùn)行超時(shí)時(shí)間,如果超過(guò)這個(gè)時(shí)間,本次健康檢查將會(huì)判定? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 為失敗,默認(rèn)為30s ? ? ? –retries=<次數(shù)>:當(dāng)連續(xù)失敗指定次數(shù)之后,則將容器狀態(tài)視為unhealthy,默認(rèn)為3次 |
| onbuild | ONBUILD是一個(gè)特殊的指令,它后面跟著的是其他指令,比如COPY、RUN等,而這些命令在當(dāng)前鏡像被構(gòu)建時(shí),并不會(huì)被執(zhí)行。只有以當(dāng)前鏡像為基礎(chǔ)鏡像去構(gòu)建下一級(jí)鏡像時(shí),才會(huì)被執(zhí)行 | ONBUILD <其他指令> |
| shell | 指定Dockerfile中 【 shell form 】命令的默認(rèn)shell。 Linux中默認(rèn)shell為 【 “/bin/sh”, “-c”】 | |
| arg | 構(gòu)建參數(shù)ARG和ENV指令一樣,都是設(shè)置環(huán)境變量。與之不同的是,ARG設(shè)置的環(huán)境變量只是在鏡像構(gòu)建時(shí)所設(shè)置的,在將來(lái)容器運(yùn)行時(shí)是不會(huì)存在這些環(huán)境變量的。但是不要因此就用ARG來(lái)保存密碼之類(lèi)的信息,因?yàn)橥ㄟ^(guò)docker history還是能夠看得到的。ARG指令與ENV指令的使用類(lèi)似 ARG構(gòu)建參數(shù)可以通過(guò)docker run命令中的--build-arg參數(shù)來(lái)進(jìn)行覆蓋 | |
| cmd | 設(shè)置指令。 Docker不是虛擬機(jī),容器就是進(jìn)程。既然是進(jìn)程,那么在啟動(dòng)容器的時(shí)候,就需要指定運(yùn)行的程序及參數(shù)。CMD就是指定默認(rèn)的容器主進(jìn)程的啟動(dòng)命令的 每個(gè) Dockerfile 只能有一條?CMD?命令。如果指定了多條命令,只有最后一條會(huì)被執(zhí)行。 如果用戶啟動(dòng)容器時(shí)候指定了運(yùn)行的命令,則會(huì)覆蓋掉?CMD?指定的命令 這里邊包括參數(shù)的一定要用雙引號(hào),就是",不能是單引號(hào)。千萬(wàn)不能寫(xiě)成單引號(hào)。 原因是參數(shù)傳遞后,docker解析的是一個(gè)JSON array 一些命令在加上sh -c之后,有可能會(huì)發(fā)生意想不到的錯(cuò)誤,因此在Dockerfile中使用RUN指令時(shí),更加推薦使用exec格式!最后需要牢記,使用docker run命令指定要執(zhí)行的命令可以覆蓋RUN指令,如果我們的docker run中指定了我們將要執(zhí)行的命令,并且在Dockerfile中也指定了CMD命令 | exec格式CMD ["executable","param1","param2"]? 使用?exec?執(zhí)行,推薦方式; shell格式CMD command param1 param2?在?/bin/sh?中執(zhí)行,提供給需要交互的應(yīng)用。 CMD ["param1","param2"]?提供給?ENTRYPOINT?的默認(rèn)參數(shù),如果CMD指令使用上面的形式,那么Dockerfile中必須要有配套的ENTRYPOINT |
| entrypoint | 設(shè)置指令 指定容器運(yùn)行程序及參數(shù) 配置容器啟動(dòng)后執(zhí)行的命令,并且不可被?docker run?提供的參數(shù)覆蓋。 每個(gè) Dockerfile 中只能有一個(gè)?ENTRYPOINT,當(dāng)指定多個(gè)時(shí),只有最后一個(gè)起效 ENTRYPOINT也更加推薦使用exec格式,ENTRYPOINT在docker run命令中同樣也可以進(jìn)行指定,只不過(guò)比CMD指令來(lái)的繁瑣一些,需要指定--entrypoint參數(shù)。同樣,在docker run命令中指定了--entrypoint參數(shù)的話,會(huì)覆蓋Dockerfile中ENTRYPOINT上的指令。 該指令的使用分為兩種情況,一種是獨(dú)自使用,另一種和CMD指令配合使用。 當(dāng)獨(dú)自使用時(shí),如果你還使用了CMD命令且CMD是一個(gè)完整的可執(zhí)行的命令,那么CMD指令和ENTRYPOINT會(huì)互相覆蓋,只有最后一個(gè)CMD或者ENTRYPOINT有效。 CMDecho?“Hello, World!”? ENTRYPOINT?ls?-l? 另一種用法和CMD指令配合使用來(lái)指定ENTRYPOINT的默認(rèn)參數(shù),這時(shí)CMD指令不是一個(gè)完整的可執(zhí)行命令,僅僅是參數(shù)部分; ENTRYPOINT指令只能使用JSON方式指定執(zhí)行命令,而不能指定參數(shù)。 CMD ["-l"]? ENTRYPOINT ["/usr/bin/ls"]? | exec格式ENTRYPOINT ["executable", "param1", "param2"] shell格式ENTRYPOINT command param1 param2(shell中執(zhí)行) |
總結(jié)
以上是生活随笔為你收集整理的DOCKERFILE参数注解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Hive常用的操作命令
- 下一篇: CentOS7下Spark集群的安装