基本結構:
Dockerfile由一行行命令語句組成,並且支持以#開頭的註釋行
Dockerfile分爲四部分:基礎鏡像信息,維護者信息、鏡像操作指令和容器啓動時執行的命令
Dockerfile指令說明:
FROM:指定所創建鏡像的基礎鏡像
MAINTAINER:指定維護者信息
RUN:運行命令
CMD:指定容器啓動時默認執行的命令
LABEL:指定生成鏡像的運數據標籤信息
EXPOSE:聲明鏡像內服務所監聽的端口
ENV:指定環境變量
ADD:複製指定的<src>路徑下的內容到容器中的<dest>路徑下,<src>可以爲URL,如果爲tar文件,會自動加壓縮到<dest>路徑下
COPY:複製本機的<src>路徑下的內容到容器中的<dest>路徑下,一般情況下推薦是用COPY而不是ADD
ENTRYPOINT:指定鏡像的默認入口
VOLUME:創建數據卷掛載點
USER:指定運行容器時的用戶名或者UID
WORKDIR:配置工作目錄
ARG:指定鏡像內使用的參數(例如版本號信息等)
ONBUILD:配置當所創建的鏡像作爲其他鏡像的基礎鏡像時,所執行的創建操作命令
STOPSIGNAL:容器退出的信號值
HEALTHCHECK:如何進行健康檢查
SHELL:指定使用shell時默認的shell類型
FROM:
執行所創建鏡像使用的基礎鏡像。如果本地不存在,會從配置Registry地址下載,格式爲
FROM <image>
或者
FROM <image>:<tag>
或者
FROM <image>@<digest>
任何Dockerfile中的第一條指令必須爲FROM指令。如果同一個Dockerfile創建多個鏡像,可以使用多個FROM指令
MAINTAINER:
指定維護者信息,格式爲MAINTAINER<name>。例如:
MAINTAINER [email protected]
改信息會寫入生成鏡像的Author屬性域中
RUN:
運行指定命令,格式爲
RUN <command>
或者
RUN ["executable", "param1", "param2"]
注意,後一個指令會被解析爲Json數組,因此必須使用雙引號。
前者默認將在shell終端中運行命令,即/bin/sh -c; 後者則使用exec執行,不會啓動shell環境。
指定使用其他終端類型可以通過第二種方式實現,例如:RUN ["/bin/bash", "-c", "echo hello"]。
每條RUN指令將在當前鏡像的基礎上執行指定的命令,並提交爲新的鏡像,當命令較長時,可以使用“\”來換行,例如:
RUN apt-get update \ && apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \ && rm -rf /var/cache/apt
CMD:
CMD指令用來指定啓動容器時默認執行的命令,它支持三種方式:
CMD ["executable", "param1", "param2"]使用exec執行,是推薦使用的方式
CMD command param1 param2 在/bin/sh中執行,提供給需要交互的應用
CDM [“param1”, "paam2"]提供給ENTRYPOINT的默認參數
每個Dockerfile只能有一條CMD命令,如果指定了多條命令,只有最後一條會被執行,如果啓動容器時手動指定了運行的命令(作爲run的參數),則會覆蓋掉CMD指令的命令
LABEL:
LABEL指令用來指定生成鏡像的元數據標籤信息
格式爲
LABEL <key>=<value> <key>=<value> <key>=<value>...
例如:
LABEL version="1.0" LABEL description="This text illustrates \ that lable-values can span multiple lines."
EXPOSE:
聲明鏡像內服務所監聽的端口
格式爲
EXPOSE <port> [<port>...]
例如:
EXPOSE 22 80 8443
注意:改指令只是起到聲明作用,並不會完成端口映射。
在啓動容器時使用-P,Docker會隨機分配一個端口,轉發到指定的端口,如果使用-p,則可以具體映射到宿主機本機的某個指定端口上。
ENV:
指定環境變量,在鏡像生成過程中被後續的RUN指令所使用,在鏡像啓動的容器中也會存在。
格式爲
ENV <key><value>
或者
ENV <key>=<value>...
例如:
ENV PG_MAJOR 9.3 ENV PG_VERSION 9.3.4 RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress &&... ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
指令指定的環境變量在運行時可以被覆蓋掉,如
docker run --env <key>=<value> built_image
ADD:
改命令將複製指定的<src>路徑下的內容到容器中的<dest>路徑下
格式爲
ADD <src> <dest>
其中<src>可以是Dockerfile所在目錄的一個相對路徑(文件或者目錄),也可以是一個URL,
還可以是一個tar文件(如果爲tar文件,會自動加壓縮到<dest>路徑下)。<dest>可以是鏡像內的絕對路徑,或相對於工作目錄<WORKDIR>的相對路徑
路徑正則格式,如:
ADD *.c /code/
COPY:
格式爲
COPY <src> <dest>
複製本地主機的<src>下的內容到鏡像中的<dest>下,目錄不存在時,會自動創建。路徑同樣支持正則格式。
當使用本地目錄爲源目錄時,推薦使用COPY
ENTRYPOINT:
指定鏡像的默認入口命令,改入口命令會在容器啓動時作爲根命令執行,所有傳入值作爲該命令的參數
支持兩種格式:
ENTRYPOINT ["EXECUTABLE", "param1" "param2"](exec調用執行)
ENTRYPOINT command param1 param2(shell中執行)
此時,CMD指令指定值將作爲根命令的參數
每個Dockerfile中只能有一個ENTRYPOINT,指定多個時,只有最後一個有效。(這點和CMD指令一樣的)
在運行時,可以被--entrypoint參數覆蓋掉,如docker run --entrypoint
VOLUME:
創建一個數據卷掛載點
格式爲
VOLUME ["/data"]
可以從本地主機或其他容器掛載數據卷,一般用來存放數據庫和需要保存的數據等。
USER:
指定運行容器時的用戶名或者UID,後續的RUN等指令也會使用指定的用戶身份
格式爲
USER daemon
當服務不需要管理員權限時,可以通過該命令指定運行用戶,並且可以在之前創建所需要的用戶,例如:
RUN groupadd -r postgres && useradd -r -g postgres
要臨時獲取管理員權限可以使用gosu或者sudo
WORKDIR:
爲後續的RUN、CMD和ENTRYOINT指令配置工作目錄
格式爲
WORKDIR /path/to/workdir
可以使用多個WORKDIR指令,後續命令如果參數是相對路徑,則會基於之前命令指定的路徑。例如:
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
最終路徑爲/a/b/c
ARG:
指定一些鏡像內使用的參數(例如版本號信息等),這些參數在執行docker build命令時才以 --build-arg<varname>=<value>格式傳入
格式爲
ARG <name>[=<default value>]
則可以使用
docker build --build-arg<name>=<value>
來指定參數值
ONBUILD:
配置當所創建的鏡像作爲其他鏡像的基礎鏡像時,所執行的創建操作指令。
格式爲
ONBUILD [INSTRUCTION]
例如:Dockerfile使用如下的內容創建了鏡像image-A;
[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src [...]
如果基於image-A創建新的鏡像時,新的Dockerfile中使用FROM image-A指定基礎鏡像,會自動執行ONBUILD指令的內容,等價於在後面添加了兩條指令
FROM image-A #Automatically run the following ADD . /app/src RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的鏡像,推薦在標籤中註明,例如:ruby:1.9-onbuild
STOPSIGNAL:
指定所創建的鏡像啓動的容器接收退出的信號值
STOPSIGNAL signal
HEALTHECK
配置所啓動的容器如何進行健康檢查,格式有兩種:
HEALTHCHECK [OPTIONS] CMD command:根據所執行命令返回值是否爲0來判斷 HEALTHCHECK NONE:禁止基礎鏡像中的健康檢查
OPTION支持:
--interval=DURATION(默認爲:30s):過多久檢查一次 --timeout=DURATION(默認爲:30s):每次檢查等待結果的超時 --retries=N(默認爲:3):如果失敗了,重試幾次才最終確定失敗
SHELL:
執行其他命令使用shell時的默認shell類型
SHELL ["executable", "parameters"]
默認值爲["/bin/sh", "-c"]
docker build創建鏡像
基本格式爲
docker build [選項] 內容路徑
該命令將讀取指定路徑下(包括子目錄)的dockerfile,並將改路徑下的所有內容發送給Docker服務端,由服務端來創建鏡像。
因此除非生成鏡像需要,否則一般建議放置Dockerfile的目錄爲空目錄。有兩點經驗:
如果使用非內容路徑下的Dockerfile,可以使用-f選項來指定其路徑
要指定生成鏡像的的標籤信息,可以使用-t選項
例如:指定Dockerfile所在路徑爲/tmp/docker_builder/,並且希望生成鏡像標籤爲build_repo/first_image,可以使用下面的命令
docker build -t build_repo/first_image /tmp/docker_builder/
Docker Hub 上的Dockerfile樣例
例如:
使用.dockerignore文件
.dockerignore
用來忽略上下文目錄中包含的一些image用不到的文件,它們不會傳送到docker daemon。規則使用go語言的匹配語法。如:
# cat .dockerignore *.rpm tmp*
這會將上下文目錄下所有.rpm和tmp.*的文件排除掉
例如:
# cat Dockerfile FROM centos:6 MAINTAINER zengcp WORKDIR /srv #RUN yum -y install vim wget LABEL version="1.0" EXPOSE 22 80 ENV JDK_VERSION 1.8 #COPY ./jdk-8u151-linux-x64.rpm /srv/ copy . ./ VOLUME "/data"
# ls aaa.temp Dockerfile jdk-8u151-linux-x64.rpm temp tmpaaa
這裏會將jdk的rpm包和tmpaaa文件排除