Dockerfile總結

是什麼?

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的關係

  1. Dockerfile必須指定至少一個CMDENTERYPOINT命令

  2. ENTERYPOINT的優先級高於CMD,如果二者同時存在,且均使用數組的方式,那麼CMD的參數會在後面追加到ENTERYPOINT命令(詳見

  3. 有多個時都只執行最後一個

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: success
    • 1: unhealthy
    • 2: 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 不能自我嵌套,且不會觸發 FROMMAINTAINER 指令
  • 使用包含 ONBUILD 指令的 Dockerfile 構建的鏡像應該使用特殊的標籤,例如 ruby:2.0-onbuild
  • ONBUILD 指令中使用 ADDCOPY 指令應該格外小心,因爲新構建過程的上下文在缺少指定原文件時會失敗

參考:

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/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章