Dockerfile是一個文本格式的配置文件,用戶可以使用Dockerfile來快速創建自定義的鏡像。
它是由多行命令組成,支持以#開頭的注釋行
配置指令
ARG
定義創建鏡像過程中使用的變量
ARG <name> [=<default value>]
再執行docker build
時,可以通過-duild-arg[=]
來為變量賦值;鏡像編譯成功之后,ARG指定的變量不再存在(ENV指定的仍然在鏡像中保留)
Docker內置了一些鏡像創建變量,用戶可以直接使用而無需聲明,包括(不區分大小寫)HTTP+PROXY HTTPS_PROXY FTP_PROXY NO-PROXY
FROM
指定創建鏡像使用的基礎鏡像
FROM <image> [AS <name>]
或者
FROM <image>:<tag> [AS <name>]
或者
FROM <image>@<digest> [AS <name>]
Dockerfile的第一條命令必須為FROM指令,如果同一個Dockerfile文件創建多個鏡像的時候,可以使用多個鏡像(每個鏡像一次)
LABEL
添加元數據標簽信息,用來鏡像以后被搜索的時候用
LABEL <key>=<value> <key>=<value> ...
EXPOSE
聲明鏡像內服務的監聽端口,運行容器的時候-P
指令就是根據這個配置來自動映射端口的
EXPOSE <port> [<port>/<protocol>...]
這個指令只是起到聲明的作用,並不會自動完成端口映射
ENV
環境變量,容器創建成功仍然存在
ENV <key> <value>
或
ENV <key>=<value> ...
這些環境變量可以在運行時被docker run --env <key>=<value>
覆蓋掉
有個需要注意的點,看下這個例子:
ENV key1=value1
ENV key1=value2 key2=${key1}
最后的結果為key1=value2 key2=value1
,因為同一條ENV語句中同時進行賦值
ENTRYPOINT
鏡像入口命令,這個命令會在啟動容器時作為根命令執行
支持兩種結構:
# 這個是在`exec`調用時執行
ENTRYPOINT ["executable","param1","param2"]
# 這個是在`shell`中執行
ENTRYPOINT command param1 param2
所有傳入值作為該命令的參數.可以這么理解:你docker run
鏡像名后面的字符串,都無腦用空格拼裝在這些命令后面
VOLUME
創建一個匿名的數據卷掛載點,可以在運行時被覆蓋
VOLUME ["/DATA"]
USER
指定運行容器時的用戶名或UID,后續的RUN命令也會使用指定的用戶身份
USER daemon
當服務不需要管理員權限時,可以通過該命令指定運行用戶
WORKDIR
為后續的RUN
,CMD
,ENTRYPOINT
配置工作目錄
WORKDIR /workdir
使用相對指令會和之前的WORKDIR指令進行拼裝,所以推薦只使用絕對路徑
ONBUILD
基於生成的鏡像再次生成子鏡像的時候,自動執行的操作命令
其他Dockerfile使用FROM引用生成的鏡像的時候會先執行鏡像中的ONBUILD語句
ONBUILD [INSTRUCTION]
STOPSIGNAL
指定所創建鏡像啟動的容器接收退出的信號值:
STOPSIGNAL signal
HEALTHCHECK
配置所啟動容器如何進行安全檢查
# 禁用鏡像安全檢查
HEALTHCHECK NONE
# 配置安全檢查的命令
HEALTHCHECK [OPTIONS] CMD command
支持的參數有:
- interval=DURATION (default: 30s) 過多久檢查一次
- timeout=DURATION (default: 30s) 每次檢查等待結果的超時時間
- retries=N (default: 3) 失敗后的重試次數
SHELL
指定其他命令使用shell是的默認shell類型
SHELL ["executable","parameters"]
默認值為["/bin/sh","-c"]
操作指令
RUN
運行指定的命令
RUN <command>
或者
RUN ["executable","param1","param2"]
前者默認使用shell終端運行,后者使用exec執行,不啟動shell環境
CMD
指定啟動容器時默認執行的命令
CMD command param1 param2
或者
CMD ["executable","param1","param2"]
或者
CMD ["param1","param2"] 提供給ENTRYPOINT的默認參數
每個Dockerfile中只能有一條CMD命令,如果指定了多條命令,只有最后一條被執行
如果用戶啟動容器時手動指定了運行的命令(作為run命令的參數),則會覆蓋掉CMD指定的命令
ADD
添加內容到鏡像
ADD <src> <dest>
復制src內容到容器內的dest路徑
其中src可以是Dockerfile所在目錄的一個相對路徑(文件或目錄);也可以是一個URL;還可以是一個tar 文件(自動解壓為目錄);dest可以是鏡像內絕對路徑,或者相 對於工作目錄(WORK.DIR)的相對路徑。
COPY
復制內容到鏡像
COPY <src> <dest>
src為本地主機Dockerfile所在目錄的相對路徑;dest為內向內絕對路徑,路徑不存在的時候,會自動創建
當使用本地目錄為源目錄時,推薦使用 COPY。
使用Dockerfile創建鏡像
編寫完Dockerfile以后,通過命令創建鏡像
$ docker build [OPTIONS] PATH | URL | -
該命令讀取指定路徑下的Dockerfile,並將該路徑下所有數據作為上下文發送給Docker服務端,Docker服務端在校驗Dockerfile格式通過后,逐條執行其中的命令,碰到ADD COPY RUN 指令會生成一層新的鏡像,如果最終創建鏡像成功,返回最終鏡像的ID
如果上下文過大,會發送大量數據到服務端,因此除非是生成鏡像必須的文件,不要放在上下文路徑;可以使用-f
顯式指定上下文路徑
用-t
為鏡像添加名稱,可以多次使用
例如
$ docker build -t builder/first_image :1.0.1 /tmp/docker_builder/
使用.dockerignore
文件
和.gitignore
文件類似,可以在上下文目錄添加規則文件,將目錄中無用的文件避免提交到服務端
例如
*/temp*
*/*/t
emp*
tmp?
- *是任意個字符
- ?是單個字符
- !是不匹配,即不忽略