Docker Review - dockerfile 入门篇
文章目錄
- Docker 鏡像、容器 、Docker file
- 概述
- Docker File文件格式
- Docker File 解讀
- 1、FROM 指定基礎(chǔ)鏡像
- 2、RUN 執(zhí)行命令
- 3、COPY 復(fù)制文件
- 4、ADD 更高級(jí)的復(fù)制文件
- 5、ENV 設(shè)置環(huán)境變量
- 6、EXPOSE
- 7、VOLUME 定義匿名卷
- 8、CMD容器啟動(dòng)命令
- 9、ENTRYPOINT入口點(diǎn)
- 10、USER 指定當(dāng)前用戶
- 11、WORKDIR 指定工作目錄
- 12、LABEL為鏡像添加元數(shù)據(jù)
- 13、ARG構(gòu)建參數(shù)
- 14、ONBUILD
- 15、STOPSIGNAL
- 16、SHELL指令
Docker 鏡像、容器 、Docker file
Docker 鏡像、容器和 Dockerfile 三者之間的關(guān)系如上圖所示
使用 Dockerfile 定義鏡像,運(yùn)行鏡像啟動(dòng)容器。
概述
官文: https://docs.docker.com/engine/reference/builder/
官文Blog :Best practices for writing Dockerfiles
-
Docker 鏡像是一個(gè)特殊的文件系統(tǒng),除了提供容器運(yùn)行時(shí)所需的程序、庫(kù)、資源、配置等文件外,還包含了一些為運(yùn)行時(shí)準(zhǔn)備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等)。
-
鏡像不包含任何動(dòng)態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會(huì)被改變
-
鏡像的定制實(shí)際上就是定制每一層所添加的配置、文件
如果我們可以把每一層修改、安裝、構(gòu)建、操作的命令都寫入一個(gè)腳本,用這個(gè)腳本來構(gòu)建、定制鏡像,那么之前提及的無法重復(fù)的問題、鏡像構(gòu)建透明性的問題、體積的問題就都會(huì)解決。這個(gè)腳本就是 Dockerfile。
-
Dockerfile 是一個(gè)文本文件,其內(nèi)包含了一條條的指令(Instruction),每一條指令構(gòu)建一層,因此每一條指令的內(nèi)容,就是描述該層應(yīng)當(dāng)如何構(gòu)建。
-
有了 Dockerfile,當(dāng)我們需要定制自己額外的需求時(shí),只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻煩。
Docker File文件格式
## Dockerfile文件格式# This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_user # Command format: Instruction [arguments / command] ..# 1、第一行必須指定 基礎(chǔ)鏡像信息 FROM ubuntu# 2、維護(hù)者信息 MAINTAINER docker_user docker_user@email.com# 3、鏡像操作指令 RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list RUN apt-get update && apt-get install -y nginx RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf# 4、容器啟動(dòng)執(zhí)行指令 CMD /usr/sbin/nginxDockerfile 分為四部分:基礎(chǔ)鏡像信息、維護(hù)者信息、鏡像操作指令、容器啟動(dòng)執(zhí)行指令。
- 開始必須要指明所基于的鏡像名稱,
- 接下來一般會(huì)說明維護(hù)者信息;
- 后面則是鏡像操作指令,例如 RUN 指令。每執(zhí)行一條RUN 指令,鏡像添加新的一層,并提交;
- 最后是 CMD 指令,來指明運(yùn)行容器時(shí)的操作命令。
Docker File 解讀
https://docs.docker.com/engine/reference/builder/#from
FROM 指定所創(chuàng)建鏡像的基礎(chǔ)鏡像 MAINTAINER 制定維護(hù)者信息 RUN 運(yùn)行命令 CMD 容器啟動(dòng)是默認(rèn)執(zhí)行的命令 LABEL 指定生成鏡像的元數(shù)據(jù)標(biāo)簽信息 EXPOSE 聲明鏡像內(nèi)服務(wù)所監(jiān)聽的端口 ENV 指定環(huán)境變量 ADD 復(fù)制指定src路徑的內(nèi)容到容器的dest路徑下,如果src為tar文件,則自動(dòng)解壓到dest路徑下 copy 復(fù)制指定src路徑的內(nèi)容到鏡像的dest路徑下 ENTERPOINT 指定鏡像的默認(rèn)入口 VOLUME 創(chuàng)建數(shù)據(jù)卷掛載點(diǎn) USER 指定運(yùn)行容器是的用戶名或UID WORKDIR 配置工作目錄 ARG 指定鏡像內(nèi)使用的參數(shù) ONBUILD 配置當(dāng)所創(chuàng)建的鏡像作為其他鏡像的基礎(chǔ)鏡像時(shí),所執(zhí)行創(chuàng)建操作指令 STOPSIGAL 容器退出信號(hào)值 HEALTHCHECK 如何進(jìn)行健康檢查 SHELL 指定使用shell的默認(rèn)shell類型下面詳細(xì)展開
1、FROM 指定基礎(chǔ)鏡像
https://docs.docker.com/engine/reference/builder/#from
FROM 指令用于指定其后構(gòu)建新鏡像所使用的基礎(chǔ)鏡像。FROM 指令必是 Dockerfile 文件中的首條命令,啟動(dòng)構(gòu)建流程后,Docker 將會(huì)基于該鏡像構(gòu)建新鏡像,FROM 后的命令也會(huì)基于這個(gè)基礎(chǔ)鏡像。
通過 FROM 指定的鏡像,可以是任何有效的基礎(chǔ)鏡像。
需要注意的事項(xiàng)如下:
- FROM 必須 是 Dockerfile 中第一條非注釋命令
- 在一個(gè) Dockerfile 文件中創(chuàng)建多個(gè)鏡像時(shí),FROM 可以多次出現(xiàn)。只需在每個(gè)新命令 FROM 之前,記錄提交上次的鏡像 ID。
- tag 或 digest 是可選的,如果不使用這兩個(gè)值時(shí),會(huì)使用 latest 版本的基礎(chǔ)鏡像
2、RUN 執(zhí)行命令
https://docs.docker.com/engine/reference/builder/#run
在鏡像的構(gòu)建過程中執(zhí)行特定的命令,并生成一個(gè)中間鏡像。
RUN <command> #exec格式 RUN ["executable", "param1", "param2"]- RUN 命令將在當(dāng)前 image 中執(zhí)行任意合法命令并提交執(zhí)行結(jié)果。命令執(zhí)行提交后,就會(huì)自動(dòng)執(zhí)行 Dockerfile 中的下一個(gè)指令。
- 層級(jí) RUN 指令和生成提交是符合 Docker 核心理念的做法。它允許像版本控制那樣,在任意一個(gè)點(diǎn),對(duì) image 鏡像進(jìn)行定制化構(gòu)建。
- RUN 指令創(chuàng)建的中間鏡像會(huì)被緩存,并會(huì)在下次構(gòu)建中使用。如果不想使用這些緩存鏡像,可以在構(gòu)建時(shí)指定 --no-cache 參數(shù),如:docker build --no-cache。
3、COPY 復(fù)制文件
https://docs.docker.com/engine/reference/builder/#copy
COPY 指令將從構(gòu)建上下文目錄中 <源路徑> 的文件/目錄復(fù)制到新的一層的鏡像內(nèi)的<目標(biāo)路徑>位置
COPY <源路徑>... <目標(biāo)路徑> COPY ["<源路徑1>",... "<目標(biāo)路徑>"]和 RUN 指令一樣,也有兩種格式,一種類似于命令行,一種類似于函數(shù)調(diào)用。
COPY package.json /usr/src/app/<源路徑>可以是多個(gè),甚至可以是通配符,其通配符規(guī)則要滿足 Go 的 filepath.Match 規(guī)則,如:
COPY hom* /mydir/ COPY hom?.txt /mydir/<目標(biāo)路徑>可以是容器內(nèi)的絕對(duì)路徑,也可以是相對(duì)于工作目錄的相對(duì)路徑(工作目錄可以用 WORKDIR 指令來指定)。目標(biāo)路徑不需要事先創(chuàng)建,如果目錄不存在會(huì)在復(fù)制文件前先行創(chuàng)建缺失目錄。
此外,還需要注意一點(diǎn),使用 COPY 指令,源文件的各種元數(shù)據(jù)都會(huì)保留。比如讀、寫、執(zhí)行權(quán)限、文件變更時(shí)間等。這個(gè)特性對(duì)于鏡像定制很有用。特別是構(gòu)建相關(guān)文件都在使用 Git 進(jìn)行管理的時(shí)候。
4、ADD 更高級(jí)的復(fù)制文件
ADD 指令和 COPY 的格式和性質(zhì)基本一致。
在 Docker 官方的 Dockerfile 最佳實(shí)踐文檔 中要求,盡可能的使用 COPY,因?yàn)?COPY 的語義很明確,就是復(fù)制文件而已,而 ADD 則包含了更復(fù)雜的功能,其行為也不一定很清晰。最適合使用 ADD 的場(chǎng)合,就是所提及的需要自動(dòng)解壓縮的場(chǎng)合。
另外需要注意的是,ADD 指令會(huì)令鏡像構(gòu)建緩存失效,從而可能會(huì)令鏡像構(gòu)建變得比較緩慢。
因此在 COPY 和 ADD 指令中選擇的時(shí)候,可以遵循這樣的原則,所有的文件復(fù)制均使用 COPY 指令,僅在需要自動(dòng)解壓縮的場(chǎng)合使用 ADD。
5、ENV 設(shè)置環(huán)境變量
設(shè)置環(huán)境變量
格式有兩種:
ENV <key> <value>這個(gè)指令很簡(jiǎn)單,就是設(shè)置環(huán)境變量而已,無論是后面的其它指令,如 RUN,還是運(yùn)行時(shí)的應(yīng)用,都可以直接使用這里定義的環(huán)境變量。
ENV MY_NAME="John Doe" ENV MY_DOG=Rex\ The\ Dog ENV MY_CAT=fluffy ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \MY_CAT=fluffy這個(gè)例子中演示了如何換行,以及對(duì)含有空格的值用雙引號(hào)括起來的辦法,這和 Shell 下的行為是一致的。
6、EXPOSE
為構(gòu)建的鏡像設(shè)置監(jiān)聽端口,使容器在運(yùn)行時(shí)監(jiān)聽
EXPOSE <port> [<port>...]EXPOSE 指令并不會(huì)讓容器監(jiān)聽 host 的端口,如果需要,需要在 docker run 時(shí)使用 -p、-P 參數(shù)來發(fā)布容器端口到 host 的某個(gè)端口上。
7、VOLUME 定義匿名卷
VOLUME用于創(chuàng)建掛載點(diǎn),即向基于所構(gòu)建鏡像創(chuàng)始的容器添加
一個(gè)卷可以存在于一個(gè)或多個(gè)容器的指定目錄,該目錄可以繞過聯(lián)合文件系統(tǒng),并具有以下功能:
- 卷可以容器間共享和重用
- 容器并不一定要和其它容器共享卷
- 修改卷后會(huì)立即生效
- 對(duì)卷的修改不會(huì)對(duì)鏡像產(chǎn)生影響
- 卷會(huì)一直存在,直到?jīng)]有任何容器在使用它
VOLUME 讓我們可以將源代碼、數(shù)據(jù)或其它內(nèi)容添加到鏡像中,而又不并提交到鏡像中,并使我們可以多個(gè)容器間共享這些內(nèi)容。
8、CMD容器啟動(dòng)命令
CMD用于指定在容器啟動(dòng)時(shí)所要執(zhí)行的命令
CMD 有以下三種格式:
CMD ["executable","param1","param2"] CMD ["param1","param2"] CMD command param1 param2省略可執(zhí)行文件的 exec 格式,這種寫法使 CMD 中的參數(shù)當(dāng)做 ENTRYPOINT 的默認(rèn)參數(shù),此時(shí) ENTRYPOINT 也應(yīng)該是 exec 格式,具體與 ENTRYPOINT 的組合使用,參考 ENTRYPOINT。
與 RUN 指令的區(qū)別:RUN 在構(gòu)建的時(shí)候執(zhí)行,并生成一個(gè)新的鏡像,CMD 在容器運(yùn)行的時(shí)候執(zhí)行,在構(gòu)建時(shí)不進(jìn)行任何操作。
9、ENTRYPOINT入口點(diǎn)
ENTRYPOINT 指定這個(gè)容器啟動(dòng)的時(shí)候要運(yùn)行的命令,可以追加命令. ENTRYPOINT 用于給容器配置一個(gè)可執(zhí)行程序。也就是說,每次使用鏡像創(chuàng)建容器時(shí),通過 ENTRYPOINT 指定的程序都會(huì)被設(shè)置為默認(rèn)程序。
ENTRYPOINT 有以下兩種形式:
ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2-
ENTRYPOINT 與 CMD 非常類似,不同的是通過docker run執(zhí)行的命令不會(huì)覆蓋 ENTRYPOINT,而docker run命令中指定的任何參數(shù),都會(huì)被當(dāng)做參數(shù)再次傳遞給 ENTRYPOINT。
-
Dockerfile 中只允許有一個(gè) ENTRYPOINT 命令,多指定時(shí)會(huì)覆蓋前面的設(shè)置,而只執(zhí)行最后的 ENTRYPOINT 指令。
-
docker run運(yùn)行容器時(shí)指定的參數(shù)都會(huì)被傳遞給 ENTRYPOINT ,且會(huì)覆蓋 CMD 命令指定的參數(shù)。如,執(zhí)行docker run <image> -d時(shí),-d 參數(shù)將被傳遞給入口點(diǎn)。
-
也可以通過docker run --entrypoint重寫 ENTRYPOINT 入口點(diǎn)。如:可以像下面這樣指定一個(gè)容器執(zhí)行程序:
10、USER 指定當(dāng)前用戶
USER 用于指定運(yùn)行鏡像所使用的用戶
USER daemon使用USER指定用戶時(shí),可以使用用戶名、UID 或 GID,或是兩者的組合。以下都是合法的指定試:
USER user USER user:group USER uid USER uid:gid USER user:gid USER uid:group使用USER指定用戶后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT 都將使用該用戶。鏡像構(gòu)建完成后,通過 docker run 運(yùn)行容器時(shí),可以通過 -u 參數(shù)來覆蓋所指定的用戶。
11、WORKDIR 指定工作目錄
WORKDIR用于在容器內(nèi)設(shè)置一個(gè)工作目錄
https://docs.docker.com/engine/reference/builder/#workdir
WORKDIR /path/to/workdir通過WORKDIR設(shè)置工作目錄后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都會(huì)在該目錄下執(zhí)行。
如,使用WORKDIR設(shè)置工作目錄:
WORKDIR /a WORKDIR b WORKDIR c RUN pwd在以上示例中,pwd 最終將會(huì)在 /a/b/c 目錄中執(zhí)行。在使用 docker run 運(yùn)行容器時(shí),可以通過-w參數(shù)覆蓋構(gòu)建時(shí)所設(shè)置的工作目錄。
12、LABEL為鏡像添加元數(shù)據(jù)
LABEL用于為鏡像添加元數(shù)據(jù),元數(shù)以鍵值對(duì)的形式指定:
LABEL <key>=<value> <key>=<value> <key>=<value> ...使用LABEL指定元數(shù)據(jù)時(shí),一條LABEL指定可以指定一或多條元數(shù)據(jù),指定多條元數(shù)據(jù)時(shí)不同元數(shù)據(jù)之間通過空格分隔。
推薦將所有的元數(shù)據(jù)通過一條LABEL指令指定,以免生成過多的中間鏡像。 如,通過LABEL指定一些元數(shù)據(jù):
LABEL version="1.0" description="artisanLearnDocker" by="artisan"指定后可以通過docker inspect查看:
docker inspect itbilu/test "Labels": {"version": "1.0","description": "artisanLearnDocker","by": "ITartisan" },13、ARG構(gòu)建參數(shù)
ARG用于指定傳遞給構(gòu)建運(yùn)行時(shí)的變量:
ARG <name>[=<default value>]如,通過ARG指定兩個(gè)變量:
ARG site ARG build_user=artisan以上我們指定了 site 和 build_user 兩個(gè)變量,其中 build_user 指定了默認(rèn)值。
在使用 docker build 構(gòu)建鏡像時(shí),可以通過 --build-arg <varname>=<value> 參數(shù)來指定或重設(shè)置這些變量的值。
docker build --build-arg site=artisan.com -t artisan/test .這樣我們構(gòu)建了 artisan/test 鏡像,其中site會(huì)被設(shè)置為 artisan.com,由于沒有指定 build_user,其值將是默認(rèn)值artisan。
14、ONBUILD
ONBUILD用于設(shè)置鏡像觸發(fā)器
ONBUILD [INSTRUCTION]當(dāng)所構(gòu)建的鏡像被用做其它鏡像的基礎(chǔ)鏡像,該鏡像中的觸發(fā)器將會(huì)被鑰觸發(fā)。 如,當(dāng)鏡像被使用時(shí),可能需要做一些處理:
[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src [...]15、STOPSIGNAL
STOPSIGNAL用于設(shè)置停止容器所要發(fā)送的系統(tǒng)調(diào)用信號(hào):
STOPSIGNAL signal所使用的信號(hào)必須是內(nèi)核系統(tǒng)調(diào)用表中的合法的值,如:SIGKILL。
16、SHELL指令
SHELL用于設(shè)置執(zhí)行命令(shell式)所使用的的默認(rèn) shell 類型:
SHELL ["executable", "parameters"]SHELL在Windows環(huán)境下比較有用,Windows 下通常會(huì)有 cmd 和 powershell 兩種 shell,可能還會(huì)有 sh。
這時(shí)就可以通過 SHELL 來指定所使用的 shell 類型:
FROM microsoft/windowsservercore# Executed as cmd /S /C echo default RUN echo default# Executed as cmd /S /C powershell -command Write-Host default RUN powershell -command Write-Host default# Executed as powershell -command Write-Host hello SHELL ["powershell", "-command"] RUN Write-Host hello# Executed as cmd /S /C echo hello SHELL ["cmd", "/S"", "/C"] RUN echo hello總結(jié)
以上是生活随笔為你收集整理的Docker Review - dockerfile 入门篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker Review - 使用do
- 下一篇: Docker Review - dock