1. 程式人生 > >一文學會Dockerfile語法

一文學會Dockerfile語法

接應上篇,續講前文。今天咱來聊一下Dockerfile的使用 。

 

雖然可以通過docker commit命令來手動建立映象,但是通過Dockerfile檔案,可以幫助我們自動建立映象,並且能夠自定義建立過程。本質上,Dockerfile就是一系列命令和引數構成的指令碼,這些命令應用於基礎映象並最終建立一個新的映象,簡化了從頭到尾的構建流程並極大地簡化了部署工作。

使用Dockerfile的優點:

  • 像程式設計一樣構建映象,支援分層構建及快取。
  • 可以快速而精確的重新建立映象以便於維護和升級。
  • 便於持續整合。
  • 可在任何地方快速構建映象。

 

一、Dockerfile構建映象步驟

 

1、建立Dockerfile檔案,名字就是Dockerfile

2、docker build Dockerfile所在路徑 -t 映象名稱[:tag]

 

二、Dockerfile指令

 

1、FORM

FORM指令是最重要的一個且必須為Dockerfile檔案開篇的第一個非註釋行,用於為映像檔案構建過程指定基準映象,後續的指令運行於此基準映象所提供的執行環境。

基準映象可以是任務可用映象檔案,預設情況下,docker build會在docker主機上查詢指定的映象檔案,如果不存在,則會從Docker Hub Registry上拉取所需的映象檔案。

也就是說,任何新建映象必須基於已有的映象進行構建。

 

格式:FROM 映象名稱[:tag]

例如:FROM ngxin

 

2、MAINTAINER

用於讓Dockerfile製作者提供本人的詳細資訊,此指令位置不限,但推薦放置FROM之後。

格式:MAINTAINER 作者資訊

例如:MAINTAINER "lsy"

 

3、LABLE

為映象指定標籤,會繼承基礎映象的LABLE,如果key相同,則覆蓋。可替代MAINTANIER使用。

 

格式:LABLE key1=value1 key2=value2

例如:LABLE author=lsy

4、RUN

指定要執行並捕獲到新容器映象中的命令,包括安裝檔案、建立檔案等,在容器建立過程中執行。

 

格式 :RUN 指令1 [&& 指令2]

 

注意:由於Dockerfile中每一個指令都會建立一層,所有層一起構成新的映象。如果指令過多的話,會變得很臃腫,增加構建時間,所以可以將指令合併執行

例如:RUN mkdir -p /usr/lsy && echo 'this is lsy file' > /usr/lsy/lsy.html

 

例如下面這個Dockerfile檔案:

基於nginx建立一個映象,並建立/usr/lsy目錄並建立lsy.html檔案

FROM nginx
MAINTAINER "lsy"
RUN mkdir -p /usr/lsy &&  echo 'this is lsy file' > /usr/lsy/lsy.html

  

使用命令進行構建

docker build ./ -t my_nginx_1:v1.1

  

 

可以看到,docker會一層層的進行構建。

 

啟動映象:

docker run --rm --name my_nginx_1 -it my_nginx_1:v1.1 /bin/bash

  

 

 

可以看到,容器中確實是執行了RUN指令。

 

5、COPY

將宿主機的檔案或者目錄拷貝到容器的檔案系統中,需相對於Dockerfile的路徑。

 

格式:COPY <src> <dest>

檔案複製準則:

  1. <src>必須是build上下文的相對路徑。
  2. <src>是目錄的話,則內部檔案或子目錄會遞迴複製,但是目錄自身不會被複制
  3. 如果指定多個src,則dest必須是一個目錄,且必須以/結尾
  4. 目標路徑如果不存在,則會自動建立

例如:把Dockerfile同目錄的test.html檔案拷貝到容器中的/usr/lsy目錄中

FROM nginx
MAINTAINER "lsy"
RUN mkdir -p /usr/lsy &&  echo 'this is lsy file' > /usr/lsy/lsy.html
COPY ./test.html /usr/lsy

  

 

使用docker build對Dockerfile進行構建:

 

啟動容器檢視檔案是否已拷貝:

 

6、ADD

功能與COPY類似,還可以使用url規範從遠端位置複製到容器中

 

格式 :ADD <source> <dest>

例如:ADD ./test.html /usr/lsy

ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe

 

7、WORKDIR

用於為其他Dockerfile指令(如 RUN、CMD)設定一個工作目錄,並且還設定用於執行容器映像例項的工作目錄。WORKDIR之後的指令都會基於設定的工作目錄中執行。

 

格式:WORKDIR 路徑

例如:將/usr/lsy設定為工作目錄,然後在目錄中建立一個a.html檔案

FROM nginx
MAINTAINER "lsy"
RUN mkdir -p /usr/lsy
WORKDIR /usr/lsy
RUN touch a.html

  

使用docker build建立映象

 

執行容器檢視:

 

可以看到,進來容器就是在工作目錄中,並且目錄中有了需要建立的檔案。

 

8、CMD

類似於RUN指令,CMD指令也可用於執行任何命令或應用程式,不過,兩者的執行時間不同。

RUN指令運行於 映象建立過程中,而CMD指令運行於基於Dockerfile構建出的映象啟動一個容器時。

CMD指令的目的在於為啟動的容器指定預設要執行的程式,且其執行結束後,容器也將終止,不過CMD指令可以被docker run的命令列引數所覆蓋。

Dockerfile中可以指定多個CMD命令,但只有最後一個才會生效。

 

格式:CMD <command>

CMD ['<executable>','<param1>','<param2>']

CMD ['<param1>','<param2>']

前兩種語法跟RUN一樣

第三種是用於為ENTERPOINT指令提供預設引數。

 

例如:CMD c:\Apache24\bin\httpd.exe -w

CMD ['/bin/bash','-c','c:\Apache24\bin\httpd.exe','-w']

 

9、ENTERPOINT

配置容器啟動後執行的命令,並且不可被 docker run 提供的引數覆蓋。每個 Dockerfile 中只能有一個ENTRYPOINT,當指定多個時,只有最後一個起效。如果有CMD,則CMD的命令被當作引數傳遞給ENTERPOINT。

不過,docker run命令的--entrypoint選項的引數可以對Dockerfile中的ENTRYPOINT進行覆蓋。

Dockerfile中可存在多個 ENTRYPOINT指令,但只有最後一個 才會執行。

 

格式:ENTRYPOINT <command>

ENTRYPOINT ['<executable>','<param1>','<param2>']

 

10、ENV

用於為映象定義所需的環境變數,並可被Dockerfile檔案中位於其後的其他指令所呼叫。

呼叫格式為${variable_name}或$variable_name

 

格式:ENV key1=value1 key2=value2

ENV key value

 

11、ARG

構建引數,作用於ENV相同,不同的是ARG的引數只在構建映象的時候起作用,也就是docker build的時候。

 

格式:ARG k=v

 

12、EXPOSE

用來指定埠,是容器內的應用可以通過埠與外界互動

作用跟docker run 命令中的 -p 一樣

 

格式:EXPOSE 埠

例如:EXPOSE 80


13、VOLUME

用於在映象中建立一個掛載點目錄,以掛載Docker Host上的卷或其他容器上的卷

如果掛載點目錄路徑下此前的檔案存在,docker run命令會在卷掛載完之後將此前的所有檔案 複製到新掛載的卷中。

 

格式:VOLUME <路徑>

VOLUME ["<路徑1>", "<路徑2>"...]

 

14、USER

用於執行後續命令的使用者和使用者組

 

格式 :USER 使用者名稱[:使用者組]

例如:USER root:root

 

15、HEALTHCHECK

用於指定某個程式或者指令來監控 docker 容器服務的執行狀態。

 

格式:HEALTHCHECK [OPTIONS] CMD command

HEALTHCHECK NONE

第一個的功能是在容器內部執行一個命令來檢查容器的健康狀況

第二個的功能是在基礎映象中取消健康檢查命令

 

[OPTIONS]的選項支援以下三中選項:

--interval=DURATION 兩次檢查預設的時間間隔為30秒

--timeout=DURATION 健康檢查命令執行超時時長,預設30秒

--retries=N 當連續失敗指定次數後,則容器被認為是不健康的,狀態為unhealthy,預設次數是3

--start-period=DURATION 容器啟動後多長時間開始執行,預設是0s

 

注意:

HEALTHCHECK命令只能出現一次,如果出現了多次,只有最後一個生效。

 

CMD後邊的命令的返回值決定了本次健康檢查是否成功,具體的返回值如下:

0: success - 表示容器是健康的

1: unhealthy - 表示容器已經不能工作了

2: reserved - 保留值

 

例如:定時 30s PING一下百度,如果PING失敗,則返回1

FROM nginx
MAINTAINER "lsy"
HEALTHCHECK --timeout=3s \
        CMD curl -f http://localhost/ || exit 1

  

使用docker build構建映象

 

執行容器,檢視日誌輸出:

 

16、ONBUILD

用於延遲構建命令的執行。簡單的說,就是 Dockerfile 裡用 ONBUILD 指定的命令,在本次構建映象的過程中不會執行(假設映象為 test-build)。當有新的 Dockerfile 使用了之前構建的映象 FROM test-build ,這是執行新映象的 Dockerfile 構建時候,會執行 test-build 的 Dockerfile 裡的 ONBUILD 指定的命令。

 

格式 :ONBUILD <其它指令>

 

17、STOPSIGNAL

當容器退出時給系統傳送什麼樣的指令

 

格式:STOPSIGNAL 指令

 

===============================

我是Liusy,一個喜歡健身的程式設計師。

獲取更多幹貨以及最新訊息,請關注公眾號:上古偽神

如果對您有幫助,點個關注就是對我最大的支援!