一文學會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 //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 //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,一個喜歡健身的程序員。

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

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

Tags: