dockerfile常用指令詳解
Dockerfile介紹
Dockerfile 是一個文字檔案,其內包含了一條條的 指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。
Docker通過docker build從上到下的順序執行Dockerfile中的一系列命令自動構建image。
dockerfile 檔案中的常見指令
FROM: 指定基礎映象
構建新映象需要指定是基於哪個映象,即指定基礎映象。 此指令通常必需放在Dockerfile檔案第一個非註釋行,後續的指令都是執行
於此基準映象所提供的執行環境。
基礎映象可以是任何可用映象檔案,預設情況下,docker build會在
使用示例:
FROM centos
FROM ubuntu:bionic
FROM mysql:5.7
LABEL: 指定映象元資料
可以指定映象元資料,如: 映象作者等
使用示例:
#您可以在一行中指定多個標籤 LABEL multi.label1="value1" multi.label2="value2" other="value3" #也可以在一條指令中指定多個標籤 LABEL multi.label1="value1" \ multi.label2="value2" \ other="value3"
RUN: 執行 shell命令
RUN 指令用來在構建映象階段需要執行 FROM 指定映象所支援的Shell命令。
通常各種基礎映象一般都支援豐富的shell命令。
注意: RUN 可以寫多個,每一個RUN指令都會建立一個映象層,所以儘可能合併成一條指令,比如將多個shell命令通過 && 連線一起成為在一條指令
每個RUN都是獨立執行的,和前一個RUN無關
使用示例:
#shell 格式: RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME' #exec 格式: RUN ["/bin/bash", "-c", "echo hello"]
ENV: 設定環境變數
ENV 可以定義環境變數和值,會被後續指令(如:ENV,ADD,COPY,RUN等)通過$KEY或${KEY}進行引用,並在容器執行時保持
使用示例:
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
COPY: 複製檔案
COPY
指令將從構建上下文目錄中 <源路徑>
的檔案/目錄複製到新的一層的映象內的 <目標路徑>
位置。
使用示例:
COPY test.txt /data/test/
COPY hom* /mydir/
COPY hom?.txt /mydir/
ADD: 複製並解壓檔案
該命令可認為是增強版的COPY,不僅支援COPY,還支援自動解壓縮。
可以將本地檔案複製到容器中,tar型別檔案會自動解壓。也可以訪問網路資源,類似wget,但來自遠端URL 的資源不會被解壓縮。
使用示例:
ADD nginx-1.14.2.tar.gz /usr/local/src/
ADD http://example.com/foobar /data
CMD: 容器啟動命令
一個容器中需要持續執行的程序一般只有一個,CMD 用來指定啟動容器時預設執行的一個命令,且其執行結束後,容器也會停止,所以一般CMD 指定的命令為持續執行且為前臺命令.
注意:
- CMD不同於RUN,CMD用於指定在容器啟動時所要執行的命令,而RUN用於指定映象構建時所要執行的命令。
- 如果docker run沒有指定任何的執行命令或者dockerfile裡面也沒有ENTRYPOINT,那麼開啟容器時就會使用執行CMD指定的預設的命令
- 每個 Dockerfile 只能有一條 CMD 命令。如指定了多條,只有最後一條被執行
- 如果使用者啟動容器時用 docker run xxx 指定執行的命令,則會覆蓋 CMD 指定的命令
使用示例:
# 使用 exec 執行,推薦方式,第一個引數必須是命令的全路徑,此種形式不支援環境變數
CMD ["executable","param1","param2"]
CMD ["nginx", "-g", "daemon off;"]
# 在 /bin/sh 中執行,提供給需要互動的應用;此種形式支援環境變數
CMD command param1 param2
CMD echo "This is a test." | wc -
# 提供給 ENTRYPOINT 命令的預設引數
CMD ["param1","param2"]
CMD ["- -help"]
ENTRYPOINT: 入口點
功能類似於CMD,配置容器啟動後執行的命令及引數
- ENTRYPOINT 不能被 docker run 提供的引數覆蓋,而是追加,即如果docker run 命令有引數,那麼引數全部都會作為ENTRYPOINT的引數
- 如果docker run 後面沒有額外引數,但是dockerfile中的CMD裡有(即上面CMD的第三種用法),即Dockerfile中即有CMD也有ENTRYPOINT,那麼CMD的全部內容會作為ENTRYPOINT的引數
- 如果docker run 後面有額外引數,同時Dockerfile中即有CMD也有ENTRYPOINT,那麼docker run後面的引數覆蓋掉CMD引數內容,最終作為ENTRYPOINT的引數
- 可以通過docker run --entrypoint string 引數在執行時替換,注意string不要加空格
- 使用CMD要在執行時重新寫命令本身,然後在後面才能追加執行引數,ENTRYPOINT則可以執行時無需重寫命令就可以直接接受新引數
- 每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最後一個生效
使用示例:
ENTRYPOINT [ "curl", "-s","https://ip.cn"]
ARG: 構建引數
ARG指令在build 階段指定變數,和ENV不同的是,容器執行時不會存在這些環境變數
如果和ENV同名,ENV覆蓋ARG變數
可以用 docker build --build-arg <引數名>=<值> 來覆蓋
使用示例:
FROM busybox
ARG user1
ARG buildno
VOLUME: 匿名卷
在容器中建立一個可以從本地主機或其他容器掛載的掛載點,一般用來存放資料庫和需要保持的資料等,一般會將宿主機上的目錄掛載至VOLUME 指令指定的容器目錄。即使容器後期被刪除,此宿主機的目錄仍會保留,從而實現容器資料的持久儲存。
使用示例:
VOLUME [ "/data1","/data2" ]
EXPOSE: 暴露埠
- 指定服務端的容器需要對外暴露(監聽)的埠號,以實現容器與外部通訊。
- EXPOSE 僅僅是宣告容器打算使用什麼埠而已,並不會真正暴露埠,即不會自動在宿主進行埠對映因此,在啟動容器時需要通過 -P 或-p ,Docker 主機才會真正分配一個埠轉發到指定暴露的端口才可使用
- 即使 Dockerfile沒有EXPOSE 埠指令,也可以通過docker run -p 臨時暴露容器內程式真正監聽的埠,所以EXPOSE 相當於指定預設的暴露埠,可以通過docker run -P 進行真正暴露
使用示例:
EXPOSE 80
WORKDIR: 指定工作目錄
為後續的 RUN、CMD、ENTRYPOINT 指令配置工作目錄,當容器執行後,進入容器內WORKDIR指定的預設目錄。
WORKDIR 指定工作目錄(或稱當前目錄),以後各層的當前目錄就被改為指定的目錄,如該目錄不存在,WORKDIR 會自行建立。
使用示例:
WORKDIR /test
ONBUILD: 子映象引用父映象的指令
可以用來配置當構建當前映象的子映象時,會自動觸發執行的指令,但在當前映象構建時,並不會執行,即延遲到子映象構建時才執行
使用示例:
ONBUILD RUN yum -y install tree
USER: 指定當前使用者
指定執行容器時的使用者名稱或 UID,後續的 RUN 也會使用指定使用者當服務不需要管理員許可權時,可以通過該命令指定執行使用者這個使用者必須是事先建立好的,否則無法切換,如果沒有指定 USER,預設是 root 身份執行
使用示例:
RUN groupadd -r mysql && useradd -r -g mysql mysql
USER mysql
HEALTHCHECK: 健康檢查
檢查容器的健康性
HEALTHCHECK [選項] CMD <命令> #設定檢查容器健康狀況的命令
HEALTHCHECK NONE #如果基礎映象有健康檢查指令,使用這行可以遮蔽掉其健康檢查指令
HEALTHCHECK 支援下列選項:
--interval=<間隔> #兩次健康檢查的間隔,預設為 30 秒
--timeout=<時長> #健康檢查命令執行超時時間,如果超過這個時間,本次健康檢查就被視為失敗,默
認 30 秒
--retries=<次數> #當連續失敗指定次數後,則將容器狀態視為 unhealthy,預設3次
--start-period=<FDURATION> #default: 0s
#檢查結果返回值:
0 #success the container is healthy and ready for use
1 #unhealth the container is not working correctly
2 #reserved do not use this exit code
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -fs http://localhost/ || exit 1