docker通過(guò)讀取Dockerfile中的指令來(lái)自動(dòng)構(gòu)建鏡像。一個(gè)Dockerfile是一個(gè)文本文檔懒棉,包含著用戶會(huì)調(diào)用的所有的命令來(lái)用于集成這個(gè)鏡像。使用 docker build 來(lái)自動(dòng)構(gòu)建命令,并在執(zhí)行成功時(shí)執(zhí)行一些命令潮孽。
用法:
docker build 命令使用dockerfile和一個(gè)構(gòu)建環(huán)境來(lái)構(gòu)建鏡像缆蝉。構(gòu)建環(huán)境是一個(gè)指定的位置或URL并且該位置有一些文件呛讲。PATH是本地文件系統(tǒng)的路徑。(默認(rèn)會(huì)使用 PATH/Dockerfile 文件來(lái)進(jìn)行構(gòu)建)URL是一個(gè)GIT倉(cāng)庫(kù)位置返奉。
一個(gè)環(huán)境可以被遞歸地處理贝搁。所以,PATH包含很多的子目錄芽偏,URL包含著倉(cāng)庫(kù)和子模塊雷逆。
如使用當(dāng)前環(huán)境作為構(gòu)建目錄(.來(lái)指定當(dāng)前構(gòu)建環(huán)境)
docker build .
構(gòu)建是被docker daemon來(lái)運(yùn)行的,而不是這個(gè)CLI污尉。構(gòu)建處理要做的第一件事就是遞歸地來(lái)發(fā)送這整個(gè)環(huán)境給守護(hù)線程膀哲。在大多數(shù)情況下,最好是一個(gè)空目錄來(lái)作為上下文環(huán)被碗,并把Dockerfile保存至那個(gè)目錄當(dāng)中某宪。僅僅添加dockerfile需要的文件
不要使用 / 目錄作為環(huán)境?!
為了在構(gòu)建環(huán)境當(dāng)中使用一個(gè)文件锐朴,Dockerfile需要通過(guò)一個(gè)指令(eg: COPY)關(guān)聯(lián)一個(gè)文件.為了提高構(gòu)建性能兴喂,可以通過(guò) .dockerignore 排除一些文件和目錄.
一般來(lái)說(shuō),Dockerfile文件命名為Dockerfile并位于上下文環(huán)境當(dāng)中焚志∫旅裕可以-f標(biāo)志來(lái)指定文件系統(tǒng)任何的Dockerfile文件來(lái)構(gòu)建。如:(注意:最后的點(diǎn)是用來(lái)指定構(gòu)建環(huán)境)
docker build -f /path/to/a/Dockerfile .
為鏡像定義倉(cāng)庫(kù)和標(biāo)簽(如果構(gòu)建成功)
docker build -t myapp:latest
Docker一條一條地執(zhí)行Dockerfile文件中的指令酱酬,并將每條指令的結(jié)果提交給新的鏡像(需要的話)壶谒,最后輸出新鏡像的id。docker守護(hù)線程會(huì)自動(dòng)清理你發(fā)送的上下文環(huán)境膳沽。
每一條指令都會(huì)獨(dú)立地運(yùn)行并且會(huì)導(dǎo)致一個(gè)新的鏡像產(chǎn)生汗菜,所以 RUN cd? /tmp 不會(huì)對(duì)下一條指令有任何的影響。
如果可能挑社,docker會(huì)重新使用緩存的鏡像去加速docker構(gòu)建陨界。會(huì)通過(guò) Using cache 將信息輸出到控制臺(tái)。
關(guān)于使用構(gòu)建緩存的進(jìn)一步說(shuō)明就不翻譯了:
Build cache is only used from images that have a local parent chain. This means that these images were created by previous builds or the whole chain of images was loaded with?docker load. If you wish to use build cache of a specific image you can specify it with?--cache-from?option. Images specified with?--cache-from?do not need to have a parent chain and may be pulled from other registries.
When you’re done with your build, you’re ready to look into?Pushing a repository to its registry.
BuildKit(構(gòu)建工具)
從18.09版本開(kāi)始滔灶,Docker支持一種后端程序用于運(yùn)行你的構(gòu)建普碎,它可以被moby/buildkit?project提供。這個(gè)?BuildKit backend 提供很多與舊版本的好處录平。如:
? ? 1. 捕獲并跳過(guò)執(zhí)行未使用的構(gòu)建階段
? ? 2. 并行構(gòu)建獨(dú)立地階段
? ? 3. 加強(qiáng)傳輸在構(gòu)建階段更改的文件
? ? 4. 捕獲并跳過(guò)傳輸沒(méi)有用的文件
? ? 5. 使用外部Dockerfile實(shí)現(xiàn)很多新的特性
? ? 6. 避免REST API的副用作影響
? ? 7. 通過(guò)自動(dòng)優(yōu)化來(lái)提升構(gòu)建緩存
? ? 使用BuildKit麻车, 設(shè)置環(huán)境變量?DOCKER_BUILDKIT=1
格式
格式如下:
# comment?
INSTRUCTION arguments?
指令非大小寫敏感缀皱,但約定是:指令大寫,參數(shù)小寫
Dockerfile必須以 FROM 指令開(kāi)始动猬,F(xiàn)ROM定義根鏡像啤斗,只能在ARG指令之后,ARG定義聲明參數(shù)赁咙。
Docker會(huì)將 # 開(kāi)頭的行作為注釋钮莲,除非這一行有有效的解析指令。其它地方出現(xiàn)#標(biāo)記彼水,都是作為參數(shù)處理崔拥。比如
# Comment
RUN echo 'we are running some #.....'
注釋不支持換行符號(hào)
解析指令(Parser directive)
解析指令是可選的,并且會(huì)影響Dockerfile中后續(xù)行處理的方式凤覆。指令不會(huì)增加構(gòu)建層链瓦,也不會(huì)再構(gòu)建步驟當(dāng)中顯示。解析指令會(huì)以一種注釋的特殊類型 如:?
# directive=value
注釋開(kāi)始后盯桦,空行或者構(gòu)建指令處理后慈俯,Docker將不會(huì)再去查找解析指令。代替的是將任何格式的指令均作為注釋拥峦,也不會(huì)去驗(yàn)證它是否是一個(gè)指令贴膘。因此,所有指令必須在Dockerfile的頂端
指令是非大小寫敏感略号。約定是
? ? 1. 字母小寫
? ? 2. 所有指令后有一個(gè)空行
指令不支持行連續(xù)字符
無(wú)效:
# direc \
tive=value
無(wú)效:重復(fù)出現(xiàn)
# directive=value1
# directive=value2
FROM ImageName
指令在構(gòu)建指令后刑峡,作為注釋:
FROM ImageName
# directive=value
視為注釋(在一個(gè)非指令之后):
# About my dockerfile
# directive=value
FROM ImageName
常用指令
syntax escape?
1.? syntax=[ remote image reference ]
eg:
# syntax=docker/dockerfile
# syntax=docker/dockerfile:1.0
# syntax=docker.io/docker/dockerfile:1
# syntax=docker/dockerfile:1.0.0-experimental
# syntax=example.com/user/repo:tag@sha256:abcdef
BuildKit?使用的時(shí)候,這個(gè)功能才會(huì)起作用
syntax指令定義Dockerfile builder的位置璃哟,builder用于構(gòu)建當(dāng)前的Dockerfile氛琢。這個(gè)Buildkit后端程序可以無(wú)縫地使用外部的builder實(shí)現(xiàn)喊递,builder由鏡像發(fā)布并在一個(gè)容器沙箱環(huán)境當(dāng)中執(zhí)行随闪。
自定義的Dockerfile實(shí)現(xiàn):
? ? 1. 在沒(méi)有更新守護(hù)線程時(shí),自動(dòng)獲取bug修復(fù)
? ? 2. 確保所有的用戶都在使用相同的實(shí)現(xiàn)來(lái)構(gòu)造你的Dockerfile
? ? 3. 在沒(méi)有更新守護(hù)線程時(shí)骚勘,使用最新的功能
? ? 4. 可以嘗試新的實(shí)驗(yàn)性特征或第三方特征
官方版本:
? ? Docker發(fā)布的用于構(gòu)建Dockerfile鏡像的鏡像的官方版本在Docker Hub的docker/dockerfile 倉(cāng)庫(kù)中铐伴。這里有兩個(gè)通道:穩(wěn)定版本和實(shí)驗(yàn)版本
兩個(gè)版本的具體詳情信息:
Stable channel follows semantic versioning. For example:
docker/dockerfile:1.0.0 - only allow immutable version 1.0.0
docker/dockerfile:1.0 - allow versions 1.0.*
docker/dockerfile:1 - allow versions 1..
docker/dockerfile:latest - latest release on stable channel
The experimental channel uses incremental versioning with the major and minor component from the stable channel on the time of the release. For example:
docker/dockerfile:1.0.1-experimental - only allow immutable version 1.0.1-experimental
docker/dockerfile:1.0-experimental - latest experimental releases after 1.0
docker/dockerfile:experimental - latest release on experimental channel
You should choose a channel that best fits your needs. If you only want bugfixes, you should use?docker/dockerfile:1.0. If you want to benefit from experimental features, you should use the experimental channel. If you are using the experimental channel, newer releases may not be backwards compatible, so it is recommended to use an immutable full version variant.
For master builds and nightly feature releases refer to the description in?the source repository.
2. escape 指令
# escape=\ (backslash)
或
# escape=` (backtick)
用來(lái)定義轉(zhuǎn)義字符, 默認(rèn)是反斜線(\)
不管是否在Docker聲明轉(zhuǎn)義字符俏讹,轉(zhuǎn)義字符都不會(huì)再RUN命令當(dāng)中執(zhí)行当宴,除了每一行的末尾。這會(huì)導(dǎo)致在使用路徑的時(shí)候泽疆,導(dǎo)致一些錯(cuò)誤户矢。如:
FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\
構(gòu)建結(jié)果:
PS C:\John> docker build -t cmd .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/2 : COPY testfile.txt c:\RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS C:\John>
解決方式:定義反斜線(`)作為轉(zhuǎn)義字符
# escape=`
環(huán)境變量替代(Environment replacement)
環(huán)境變量(通過(guò)ENV語(yǔ)句進(jìn)行聲明)可以被用于適當(dāng)?shù)闹噶町?dāng)中被插值到Dockerfile當(dāng)中。轉(zhuǎn)義也可以被處理用于包含像變量的語(yǔ)言到語(yǔ)句當(dāng)中殉疼。
環(huán)境變量通過(guò)符號(hào)顯示梯浪,要么是 $variable_name 或者 ${variable_name?}.他們都會(huì)被同樣地被處理捌年。
同時(shí)支持一些bash標(biāo)示符:
? ? ${ variable: -word} word是默認(rèn)值
? ? ${ variable: +word} 變量為word時(shí)有效,否則返回的是空字符串
支持環(huán)境變量的指令:
ADD COPY ENV EXPOSE FROM LABEL STOPSIGNAL USER VOLUME WORKDIR
ONBUILD當(dāng)和以上結(jié)合時(shí)挂洛,也會(huì)支持
環(huán)境變量替換將在整個(gè)指令中對(duì)每個(gè)變量使用相同的值
ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc
def的值是hello? ghi的值是 bye
.dockerignore file
避免發(fā)送大型和敏感文件或路徑到守護(hù)線程當(dāng)中礼预,比如node里面的node_module路徑,這個(gè)路徑是很龐大且文件數(shù)量很多虏劲,如果用于構(gòu)建鏡像托酸,這會(huì)耗費(fèi)很多的時(shí)間。
很多管理工具都會(huì)有這種類似的文件柒巫,具體見(jiàn)以下鏈接:http://home.hyywk.top:4000/engine/reference/builder/#dockerignore-file
FROM 控制命令
FROM <image> [ AS <name>]
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
FROM會(huì)初始化一個(gè)新構(gòu)建的階段并設(shè)置基本鏡像用于子序列指令励堡。比如,一個(gè)有效的Dockerfile必須以一個(gè)FROM命令開(kāi)始堡掏。image可以是任何有效的鏡像念秧,并容易從鏡像倉(cāng)庫(kù)中拉取。
? ? 1. ARG 是唯一一個(gè)指令可以先于FROM指令布疼,http://home.hyywk.top:4000/engine/reference/builder/#understand-how-arg-and-from-interact
? ? 2. FROM 可以在一個(gè)Dockerfile文件中創(chuàng)建多個(gè)鏡像文件摊趾,每一個(gè)創(chuàng)建后會(huì)輸出一個(gè)鏡像id
? ? 3. 可以為某個(gè)構(gòu)建起別名,用于后續(xù)的FROM命令和COPY --from=<name|index>命令相關(guān)的鏡像來(lái)基于這個(gè)階段
? ? 4. tag或digest是可選的游两,默認(rèn)是latest砾层。如果找不到tag值,則會(huì)報(bào)錯(cuò)贱案。
理解 ARG 和 FROM的交互
FROM 命令支持通過(guò)任何ARG命令聲明的變量
如:
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD? /code/run-app
FROM extras:${CODE_VERSION}
CMD? /code/run-extras
一個(gè)ARG在FROM之前聲明的變量是在構(gòu)建作用域之外肛炮,所以不能在FROM之后再次使用,如果要使用之前聲明的默認(rèn)值宝踪,需要在FROM再次無(wú)參數(shù)聲明:
ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version
RUN命令(構(gòu)建時(shí)運(yùn)行)
格式:
RUN <command>?(shell?form, the command is run in a shell, which by default is?/bin/sh -c?on Linux or?cmd /S /C?on Windows)
RUN ["executable", "param1", "param2"]?(exec?form)
RUN指令會(huì)在當(dāng)前鏡像的頂層執(zhí)行一些指令侨糟,并提交這個(gè)結(jié)果用于Dockerfile的下一步
shell from可以更改默認(rèn)shell,使用 \ 繼續(xù)寫入第二行的執(zhí)行命令瘩燥,如下:
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
exec from 形式更改默認(rèn)shelll秕重,且exec from格式必須使用雙括號(hào)格式
RUN ["/bin/bash", "-c", "echo hello"]
exec form進(jìn)一步說(shuō)明,exec form形式不會(huì)調(diào)用一個(gè)命令行外殼厉膀。不會(huì)有shell處理溶耘,RUN [ "echo", "$home" ],將不會(huì)被變量替代。如果希望shell處理服鹅,要么使用shell form形式凳兵,要么直接執(zhí)行一個(gè)shell:RUN [ "sh", "-c", "echo $HOME" ]
exec form必須使用雙引號(hào),并且必要時(shí)企软,必須使用轉(zhuǎn)義庐扫,如windows下的路徑
RUN命令在下一次構(gòu)建執(zhí)行時(shí),會(huì)默認(rèn)使用緩存。不是用緩存
docker build --no-cache
Known issues(RUN)
http://home.hyywk.top:4000/engine/reference/builder/#known-issues-run
CMD(容器運(yùn)行時(shí)執(zhí)行)
CMD命令有三種格式
CMD ["executable","param1","param2"]?(exec?form, this is the preferred form)
CMD ["param1","param2"]?(as?default parameters to ENTRYPOINT)
CMD command param1 param2?(shell?form)
CMD命令只能在Dockerfile當(dāng)中有一個(gè)(the latest有效)形庭。
CMD的主要目的是為執(zhí)行容器提供默認(rèn)值杰妓。這些默認(rèn)包括可執(zhí)行程序或者可忽略的執(zhí)行程序,在那種情況下你必須定義一個(gè)ENTRYPOINT命令
docker容器的主線程(dockfile中CMD執(zhí)行的命令)結(jié)束碘勉,容器會(huì)退出
1. 如果CMD為ENTRYPOINT提供默認(rèn)參數(shù)巷挥,則必須都要是JSON array format
2. exec form使用雙引號(hào)
LABEL(添加meta信息)
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
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."
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
定義容器在運(yùn)行時(shí)監(jiān)聽(tīng)的網(wǎng)絡(luò)端口(tcp或udp類型,默認(rèn)是tcp)验靡,該命令僅用于文檔聲明倍宾,不會(huì)確切地堅(jiān)定,應(yīng)通過(guò)docker run -p 選項(xiàng)來(lái)執(zhí)行運(yùn)行時(shí)監(jiān)聽(tīng)的端口胜嗓。
示例:
expose 80/udp
expose 80/tcp
ENV 為聲明環(huán)境變量(可在容器中或構(gòu)建階段直接使用)
格式
ENV <key> <value>
ENV <key>=<value> ...
示例:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
? ? myCat=fluffy
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
ADD
該命令用從src中的 文件高职、目錄和遠(yuǎn)程url復(fù)制,添加到 dest當(dāng)中
格式:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]?(this form is required for paths containing whitespace)
<src>可以通過(guò)通配符號(hào)來(lái)匹配辞州,如 * ??
具體匹配規(guī)則:http://golang.org/pkg/path/filepath#Match
<dest> 是絕對(duì)路徑或者相對(duì)WORKDIR的相對(duì)路徑
ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
ADD test /absoluteDir/? ? ? ? # adds "test" to /absoluteDir/
新的文件被復(fù)制之后怔锌,默認(rèn)UID和GID(權(quán)限控制)均為0,使用--chown來(lái)定義給定的用戶名、組名或者UID和GID的結(jié)合变过,可以提供一個(gè)用戶名沒(méi)有組名埃元、一個(gè)沒(méi)有g(shù)id的uid會(huì)使用相同的uid作為gid、如果提供了用戶名或組名媚狰,容器的根文件系統(tǒng)/etc/passwd和/etc/group文件將分別用于將名稱轉(zhuǎn)換為整數(shù)UID或GI岛杀,eg:
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
如果<src>是一個(gè)目錄,則復(fù)制目錄的全部?jī)?nèi)容崭孤,包括文件系統(tǒng)元數(shù)據(jù)类嗤。
注意:目錄本身不會(huì)被復(fù)制,只是它的內(nèi)容辨宠。
如果<src>是以可識(shí)別壓縮格式(identity遗锣、gzip、bzip2或xz)的本地tar歸檔文件嗤形,則將其解壓為目錄精偿。來(lái)自遠(yuǎn)程url的資源不會(huì)被解壓。復(fù)制或解壓目錄時(shí)派殷,其行為與tar -x相同还最,結(jié)果為:
在目標(biāo)路徑和
源樹(shù)的內(nèi)容,其中沖突的解決有利于“2”毡惜。“在一個(gè)文件一個(gè)文件的基礎(chǔ)上斯撮。
注意:文件是否被識(shí)別為可識(shí)別的壓縮格式经伙,完全取決于文件的內(nèi)容,而不是文件的名稱。例如帕膜,如果一個(gè)空文件恰好以.tar結(jié)尾枣氧。這將不會(huì)被識(shí)別為壓縮文件,也不會(huì)生成任何類型的解壓縮錯(cuò)誤消息垮刹,而是將文件簡(jiǎn)單地復(fù)制到目的地达吞。
如果<src>是任何其他類型的文件,它將與它的元數(shù)據(jù)一起單獨(dú)復(fù)制荒典。在這種情況下酪劫,如果<dest>以斜杠/結(jié)尾,它將被認(rèn)為是一個(gè)目錄寺董,<src>的內(nèi)容將寫在<dest>/base(<src>)覆糟。
如果指定了多個(gè)<src>資源,要么直接指定遮咖,要么使用通配符指定滩字,那么<dest>必須是一個(gè)目錄,并且必須以斜杠/結(jié)束御吞。
如果<dest>沒(méi)有結(jié)尾斜杠麦箍,它將被認(rèn)為是一個(gè)常規(guī)文件,<src>的內(nèi)容將寫在<dest>陶珠。
如果<dest>不存在内列,它將與其路徑中所有丟失的目錄一起創(chuàng)建。
COPY
幾乎和ADD一樣背率,不同之處就是话瞧,只能使用本地文件
ENTRYPOINT
配置容器可作為一個(gè)可執(zhí)行文件運(yùn)行
格式:
ENTRYPOINT ["executable", "param1", "param2"]?(exec?form, preferred)
ENTRYPOINT command param1 param2?(shell?form)
功能是啟動(dòng)時(shí)的默認(rèn)命令
語(yǔ)法如下:
1. ENTRYPOINT ["executable", "param1", "param2"]
2. ENTRYPOINT command param1 param2
ENTRYPOINT的命令作為 /bin/sh -c的子命令,意味著不會(huì)接受Unix信號(hào)寝姿,所以執(zhí)行的程序的pid不會(huì)是1交排,也不會(huì)接受docker stop <container>.發(fā)送的信號(hào)
如果從上到下看到這里的話,那么你應(yīng)該對(duì)這兩種語(yǔ)法很熟悉啦饵筑。
第二種就是寫shell
第一種就是可執(zhí)行文件加參數(shù)
與CMD比較說(shuō)明(這倆命令太像了埃篓,而且還可以配合使用):
1. 相同點(diǎn):
只能寫一條,如果寫了多條根资,那么只有最后一條生效
容器啟動(dòng)時(shí)才運(yùn)行架专,運(yùn)行時(shí)機(jī)相同
2. 不同點(diǎn):
?ENTRYPOINT不會(huì)被運(yùn)行的command覆蓋,而CMD則會(huì)被覆蓋
?如果我們?cè)贒ockerfile種同時(shí)寫了ENTRYPOINT和CMD玄帕,并且CMD指令不是一個(gè)完整的可執(zhí)行命令部脚,那么CMD指定的內(nèi)容將會(huì)作為ENTRYPOINT的參數(shù)
如下:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
如果我們?cè)贒ockerfile種同時(shí)寫了ENTRYPOINT和CMD,并且CMD是一個(gè)完整的指令裤纹,那么它們兩個(gè)會(huì)互相覆蓋委刘,誰(shuí)在最后誰(shuí)生效
如下:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ls -al
那么將執(zhí)行l(wèi)s -al ,top -b不會(huì)執(zhí)行。
官方比較圖:
VOLUME?
可實(shí)現(xiàn)掛載功能,可以將內(nèi)地文件夾或者其他容器種得文件夾掛在到這個(gè)容器種
語(yǔ)法為:
VOLUME ["/data"]
說(shuō)明:
? ?["/data"]可以是一個(gè)JsonArray 锡移,也可以是多個(gè)值呕童。所以如下幾種寫法都是正確的
VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db
一般的使用場(chǎng)景為需要持久化存儲(chǔ)數(shù)據(jù)時(shí)
容器使用的是AUFS,這種文件系統(tǒng)不能持久化數(shù)據(jù)淆珊,當(dāng)容器關(guān)閉后夺饲,所有的更改都會(huì)丟失。
所以當(dāng)數(shù)據(jù)需要持久化時(shí)用這個(gè)命令施符。\
User?
設(shè)置啟動(dòng)容器的用戶往声,可以是用戶名或UID,所以操刀,只有下面的兩種寫法是正確的
USER daemo
USER UID
注意:如果設(shè)置了容器以daemon用戶去運(yùn)行烁挟,那么RUN, CMD 和 ENTRYPOINT 都會(huì)以這個(gè)用戶去運(yùn)行
WORKDIR
語(yǔ)法:
WORKDIR /path/to/workdir
設(shè)置工作目錄,對(duì)RUN,CMD,ENTRYPOINT,COPY,ADD生效骨坑。如果不存在則會(huì)創(chuàng)建撼嗓,也可以設(shè)置多次。
如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
pwd執(zhí)行的結(jié)果是/a/b/c
WORKDIR也可以解析環(huán)境變量
如:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
pwd的執(zhí)行結(jié)果是/path/$DIRNAME
ARG
語(yǔ)法:
ARG <name>[=<default value>]
設(shè)置變量命令欢唾,ARG命令定義了一個(gè)變量且警,在docker build創(chuàng)建鏡像的時(shí)候,使用 --build-arg <varname>=<value>來(lái)指定參數(shù)
如果用戶在build鏡像時(shí)指定了一個(gè)參數(shù)沒(méi)有定義在Dockerfile種礁遣,那么將有一個(gè)Warning
提示如下:
[Warning] One or more build-args [foo] were not consumed.
我們可以定義一個(gè)或多個(gè)參數(shù)斑芜,如下:
FROM busybox
ARG user1
ARG buildno
...
也可以給參數(shù)一個(gè)默認(rèn)值:
FROM busybox
ARG user1=someuser
ARG buildno=1
...
如果我們給了ARG定義的參數(shù)默認(rèn)值,那么當(dāng)build鏡像時(shí)沒(méi)有指定參數(shù)值祟霍,將會(huì)使用這個(gè)默認(rèn)值
ONBUILD
語(yǔ)法:
ONBUILD [INSTRUCTION]
這個(gè)命令只對(duì)當(dāng)前鏡像的子鏡像生效杏头。
比如當(dāng)前鏡像為A,在Dockerfile種添加:
ONBUILD RUN ls -al
這個(gè) ls -al 命令不會(huì)在A鏡像構(gòu)建或啟動(dòng)的時(shí)候執(zhí)行
此時(shí)有一個(gè)鏡像B是基于A鏡像構(gòu)建的沸呐,那么這個(gè)ls -al 命令會(huì)在B鏡像構(gòu)建的時(shí)候被執(zhí)行醇王。
STOPSIGNAL
語(yǔ)法:
STOPSIGNAL signal
STOPSIGNAL命令是的作用是當(dāng)容器推出時(shí)給系統(tǒng)發(fā)送什么樣的指令
HEALTHCHECK
?容器健康狀況檢查命令
語(yǔ)法有兩種:
1. HEALTHCHECK [OPTIONS] CMD command
2. HEALTHCHECK NONE
第一個(gè)的功能是在容器內(nèi)部運(yùn)行一個(gè)命令來(lái)檢查容器的健康狀況
第二個(gè)的功能是在基礎(chǔ)鏡像中取消健康檢查命令
[OPTIONS]的選項(xiàng)支持以下三中選項(xiàng):
? ? --interval=DURATION 兩次檢查默認(rèn)的時(shí)間間隔為30秒
? ? --timeout=DURATION 健康檢查命令運(yùn)行超時(shí)時(shí)長(zhǎng),默認(rèn)30秒
? ? --retries=N 當(dāng)連續(xù)失敗指定次數(shù)后崭添,則容器被認(rèn)為是不健康的寓娩,狀態(tài)為unhealthy,默認(rèn)次數(shù)是3
注意:
HEALTHCHECK命令只能出現(xiàn)一次呼渣,如果出現(xiàn)了多次棘伴,只有最后一個(gè)生效。
CMD后邊的命令的返回值決定了本次健康檢查是否成功屁置,具體的返回值如下:
0: success - 表示容器是健康的
1: unhealthy - 表示容器已經(jīng)不能工作了
2: reserved - 保留值
例子:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
健康檢查命令是:curl -f http://localhost/ || exit 1
兩次檢查的間隔時(shí)間是5秒
命令超時(shí)時(shí)間為3秒
ONBUILD?
?ONBUILD 是一個(gè)特殊的指令焊夸,它后面跟的是其它指令,比如 RUN , COPY 等缰犁,而這些指令淳地,在當(dāng)前鏡像構(gòu)建時(shí)并不會(huì)被執(zhí)行怖糊。只有當(dāng)以當(dāng)前鏡像為基礎(chǔ)鏡像帅容,去構(gòu)建下一級(jí)鏡像的時(shí)候才會(huì)被執(zhí)行颇象。
?Dockerfile 中的其它指令都是為了定制當(dāng)前鏡像而準(zhǔn)備的,唯有 ONBUILD 是為了幫助別人定制自己而準(zhǔn)備的并徘。