是什麼?
Dockerfile是一個包含所有可以用來組合鏡像的命令的文本文檔。可以通過dcoker build
命令從Dockerfile構建鏡像。
docker build -f /path/to/a/Dockerfile .
-f 指定Dockerfile的路徑
指令
# Comment # 使用#標識註釋
FROM:指定基礎鏡像
FROM必須爲第一條指令。
FROM <image>[:<tag>] [AS <name>]
: 設置基礎鏡像
- 不指定標籤時,默認使用latest版本
MAINTAINER:維護者信息
Syntax: MAINTAINER <name>
RUN:執行命令
用於指定 docker build 過程中運行的程序,其可以是任何命令
-
RUN命令支持兩種格式:shell格式和exec格式。
-
每條RUN指令將當前的鏡像基礎上的圖層上執行指令,並提交爲新的鏡像,命令較長的時候可以使用\來換行。建議不要使用太多的RUN操作,考慮封裝成shell腳本,或者用一條語句組裝起來。所以正確寫法應該是:
RUN buildDeps='gcc libc6-dev make' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \ && mkdir -p /usr/src/redis \ && rm -r /usr/src/redis \ && apt-get purge -y --auto-remove $buildDeps
shell 格式
Syntax: RUN <command>
示例:
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
- shell格式是以
/bin/sh -c
來運行它(推薦)- 這意味着此進程在容器中的
PID
不爲 1,不能接收 Unix 信號(比如kill信號),因此,當使用docker stop <container>
命令停止容器時,此進程接收不到SIGTERM
信號;
- 這意味着此進程在容器中的
exec 格式
Syntax: RUN ["<executable", "<param1>", "<param2>"]
其中 <executable>
爲要運行的命令
COPY:複製文本
複製本機文件到容器目錄下
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
<源路徑> 指本機的src目錄,可以是多個、以及使用通配符,通配符規則滿足Go的filepath.Match 規則,如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<目標路徑>使用 COPY 指令,源文件的各種元數據都會保留。比如讀、寫、執行權限、文件變更時間等。
ADD:高級複製文件
複製本機文件到容器目錄下,且支持從一個URL或一個tar文件拉取文件
- tar文件會自動解壓爲目錄
- 原路徑是URL時 ,下載後的文件權限自動設置爲 600
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
命令COPY和ADD命令有什麼區別?
一般而言,雖然ADD並且COPY在功能上類似。唯一區別在於是否支持從遠程URL獲取資源。COPY指令只能從執行docker build所在的主機上讀取資源並複製到鏡像中。而ADD指令還支持通過URL從遠程服務器讀取資源並複製到鏡像中。
滿足同等功能的情況下,推薦使用COPY指令。ADD指令更擅長讀取本地tar文件並解壓縮。
CMD:容器啓動命令
在運行鏡像文件啓動容器時,指定默認要運行的程序,且其運行結束後,容器也將終止。?
- CMD指定的命令可被docker run時指定的cmd命令覆蓋
- 可以存在多個
CMD
指令,但僅有最後一個會生效
Syntax
CMD <command>
CMD ["<executable", "<param1>", "<param2>"]
CMD ["<param1>", "<param2>"]
前兩種語法格式的意義同 RUN
第三種語法則用於 ENTRYPOINT
指令提供默認參數
ENTRYPOINT:入口點
同CMD,指定容器啓動程序及參數。
- 與
CMD
不同的是,由ENTRYPOINT
啓動的程序不會被docker run
命令行指定的參數所覆蓋,而且,這些命令行參數會被當做參數傳遞給ENTRYPOINT
指定的程序 docker run
命令的--entrypoint
選項的參數可覆蓋ENTRYPOINT
指令指定的程序- 可以存在多個
ENTRYPOINT
指令,但僅有最後一個會生效
Syntax:
ENTRYPOINT <command>
ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
命令CMD和ENTERYPOINT的關係
-
Dockerfile必須指定至少一個
CMD
或ENTERYPOINT
命令 -
ENTERYPOINT
的優先級高於CMD
,如果二者同時存在,且均使用數組的方式,那麼CMD
的參數會在後面追加到ENTERYPOINT
命令(詳見)
-
有多個時都只執行最後一個
ENV:設置環境變量
Syntax:ENV <key> <value> \ <key>=<value>
-
在其他指令中可以直接引用ENV設置的環境變量。
-
可以使用
docker run --env <key>=<value>
修改環境變量
ARG:構建參數
Syntax:ARG <name>[=<default value>]
: docker file
中的變量
與ENV不同的是,容器運行時不會存在這些環境變量。
可以用 docker build --build-arg <參數名>=<值>
來覆蓋。
VOLUME:定義匿名卷
在製作鏡像時掛載卷。會在宿主機上自動生成一個對應的共享目錄。
- 一個卷可以存在於一個或多個容器的指定目錄,該目錄可以繞過聯合文件系統
- 修改卷後立即生效
- 卷的修改不影響鏡像
Syntax:VOLUME ["/path"]
EXPOSE:暴露端口
容器監聽的端口和協議,供容器外部連接使用。默認使用TCP
-
運行容器時可以通過制定
- p
重寫該配置docker run -p 80:80/tcp -p 80:80/udp ...
Syntax:EXPOSE <port> [<port>/<protocol>...]
WORKDIR:指定工作目錄
爲後續命令指定工作目錄
- 注意再次指定目錄時如果是相對路徑要基於之前的命令
Syntax:WORKDIR <工作目錄路徑>
USER:指定當前用戶
指定容器運行時的用戶名或UID,後續的RUN也會使用指定的用戶。
- 這個用戶必須是事先建立好的,否則無法切換。
Syntax:USER <user>[:<group>] / <UID>[:<GID>]
HEALTHCHECK:健康檢查
設置檢查容器健康狀況的命令
HEALTHCHECK [選項] CMD <命令>
HEALTHCHECK NONE
:如果基礎鏡像有健康檢查指令,使用這行可以屏蔽掉其健康檢查指令
HEALTHCHECK 支持下列選項:
-
--interval=<間隔>
:兩次健康檢查的間隔,默認爲 30 秒; -
--timeout=<時長>
:健康檢查命令運行超時時間,如果超過這個時間,本次健康檢查就被視爲失敗,默認 30 秒; -
--retries=<次數>
:當連續失敗指定次數後,則將容器狀態視爲 unhealthy ,默認 3次。 -
command 的 exit status 表明容器的健康狀態
0
: success1
: unhealthy2
: reserved - do not use this exit code (可以自己定義)
-
例子(\ 表示換行)
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
執行exit可使shell以指定的狀態值退出。
LABEL:鏡像標籤
LABEL <key>=<value> <key>=<value> ...
: 鏡像標籤,方便使用
ONBUILD:定義觸發器
Syntax
ONBUILD <INSTRUCTION>
Dockerfile作爲鏡像文件,會作爲base image被另一個Dockerfile使用,來構建新的鏡像文件。在新鏡像文件執行FROM
時,會觸發base image的Dockerfile中定義的觸發器
- 儘管任何指令都可以註冊成爲觸發器指令,但
ONBUILD
不能自我嵌套,且不會觸發FROM
和MAINTAINER
指令 - 使用包含
ONBUILD
指令的Dockerfile
構建的鏡像應該使用特殊的標籤,例如ruby:2.0-onbuild
- 在
ONBUILD
指令中使用ADD
或COPY
指令應該格外小心,因爲新構建過程的上下文在缺少指定原文件時會失敗
參考:
https://www.jianshu.com/p/168fbb97b447
https://www.jianshu.com/p/ed4818838385
https://www.jianshu.com/p/c39e32396319
https://docs.docker.com/engine/reference/builder/