Dockerfile介紹
Dockerfile 是一個文本文件,其內包含了一條條的 指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。
Docker通過docker build從上到下的順序運行Dockerfile中的一系列命令自動構建image。
dockerfile 文件中的常見指令
FROM: 指定基礎鏡像
構建新鏡像需要指定是基於哪個鏡像,即指定基礎鏡像。 此指令通常必需放在Dockerfile文件第一個非注釋行,后續的指令都是運行
於此基准鏡像所提供的運行環境 。
基礎鏡像可以是任何可用鏡像文件,默認情況下,docker build會在docker主機本地查找指定的鏡像文件,在其不存在時,則會從Docker Hub Registry上拉取所需的鏡像文件.如果找不到指定的鏡像文件,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