docker教程-dockerfile語法

  • FROM關鍵字

        指定基礎鏡像,而且必須是第一條指令。若是不以任何鏡像爲基礎,那麼寫法爲:FROM scratch。同時意味着接下來所寫的指令將做爲鏡像的第一層開始,語法:python

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest> 

        三種寫法,其中<tag>和<digest> 是可選項,若是沒有選擇,那麼默認值爲latest,爲了安全,儘可能使用官方image做爲base imagemysql

 例:linux

FROM scratch #製做base image
FROM centos  #以centos做爲base image
  • LABEL關鍵字

        爲鏡像指定標籤,語法:sql

LABEL <key>=<value> <key>=<value> <key>=<value> ...

        一個Dockerfile種能夠有多個LABEL,以下:docker

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

     可是並不建議這樣寫,最好就寫成一行,如太長鬚要換行的話則使用\符號shell

      以下:vim

LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

    說明:LABEL會繼承基礎鏡像種的LABEL,如遇到key相同,則值覆蓋windows

例:centos

LABEL maintainer="asd@163.com"  #維護者信息
LABEL version="1.0"             #版本
LABEL description="這是描述"     #鏡像描述信息
  • RUN關鍵字

    功能爲運行指定的命令,每運行一次RUN對image而言都生成新的一層,RUN命令有兩種格式安全

1. RUN <command>
2. RUN ["executable", "param1", "param2"]

    第一種後邊直接跟shell命令

  • 在linux操做系統上默認 /bin/sh -c

  • 在windows操做系統上默認 cmd /S /C

    第二種是相似於函數調用。可將executable理解成爲可執行文件,後面就是兩個參數。

    兩種寫法比對:

  • RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME
  • RUN ["/bin/bash", "-c", "echo hello"]

    注意:多行命令不要寫多個RUN,緣由是Dockerfile中每個指令都會創建一層.多少個RUN就構建了多少層鏡像,會形成鏡像的臃腫、多層,不只僅增長了構件部署的時間,還容易出錯。

當命令較多,或較長時,建議將命令換行,RUN書寫時的換行符是 \

例:

RUN yum update && yum install -y vim \
    python-dev
RUN apt-get update && apt-get install -y perl \
    pwgen --no-install-recommends && rm -rf \
    /var/lib/apt/list/*
  • WORKDIR關鍵字

      設置工做目錄,對RUN,CMD,ENTRYPOINT,COPY,ADD生效。至關於 cd,若是不存在要打開的目錄則會建立,能夠設置屢次。語法:

WORKDIR /path/to/workdir

    例:

WORKDIR /ROOT  #將工做目錄切換到root下
WORKDIR /test  #將工做目錄切換到test目錄  沒有則建立
WORKDIR demo   #結合上一句 此時工做目錄被切換到/test/demo目錄下

  儘可能使用WORKDIR,而不使用RUN cd,儘可能使用局對目錄。

  • ADD關鍵字

       一個複製命令,把文件複製到鏡像中。若是把宿主機與容器想象成兩臺linux服務器的話,那麼這個命令就相似於scp,只是scp須要加用戶名和密碼的權限驗證,而ADD不用。語法以下:

1. ADD <src>... <dest>
2. ADD ["<src>",... "<dest>"]

<dest>路徑的填寫能夠是容器內的絕對路徑,也能夠是相對於工做目錄的相對路徑

<src>能夠是一個本地文件或者是一個本地壓縮文件,還能夠是一個url,若是把<src>寫成一個url,那麼ADD就相似於wget命令,ADD不只能夠添加一個文件到指定目錄,並且還能夠將添加的壓縮文件解壓縮,

如如下寫法都是能夠的:

  • ADD test relativeDir/  #將test複製到容器內,相對於當前工做目錄下的relativeDir目錄中
  • ADD test /relativeDir #將test複製到容器內根目錄下relativeDir目錄中
  • ADD http://example.com/foobar / #將網絡文件下載到根目錄下

    儘可能不要把<scr>寫成一個文件夾,若是<src>是一個文件夾了,將複製整個目錄的內容,包括文件系統元數據

    有以下注意事項:

    一、若是源路徑是個文件,且目標路徑是以 / 結尾, 則docker會把目標路徑看成一個目錄,會把源文件拷貝到該目錄下。若是目標路徑不存在,則會自動建立目標路徑。

    二、若是源路徑是個文件,且目標路徑是否是以 / 結尾,則docker會把目標路徑看成一個文件。若是目標路徑不存在,會以目標路徑爲名建立一個文件,內容同源文件;若是目標文件是個存在的文件,會用源文件覆蓋它,固然只是內容覆蓋,文件名仍是目標文件名。若是目標文件實際是個存在的目錄,則會源文件拷貝到該目錄下。 注意,這種狀況下,最好顯示的以 / 結尾,以免混淆。

    三、若是源路徑是個目錄,且目標路徑不存在,則docker會自動以目標路徑建立一個目錄,把源路徑目錄下的文件拷貝進來。若是目標路徑是個已經存在的目錄,則docker會把源路徑目錄下的文件拷貝到該目錄下。

    四、若是源文件是個歸檔文件(壓縮文件),則docker會自動幫解壓。

  • COPY關鍵字

    看這個名字就知道,又是一個複製命令,與ADD用法基本相同,COPY的<src>只能是本地文件,語法以下:

1. COPY <src>... <dest>
2. COPY ["<src>",... "<dest>"]

    例:

ADD hello /  #將hello文件複製到容器內根目錄下
ADD test.tar.gz /   #將壓縮文件添加到容器內根目錄下並解壓
WORKDIR /root  #將工做目錄切換到root目錄下
ADD hello test/   #將hello文件添加到/root/test目錄下
WORKDIR /root  #將工做目錄切換到root目錄下
copy hello test/ #將hello文件複製到/root/test
  • ENV關鍵字

    功能爲設置環境變量設置常量,語法有兩種:   

1. ENV <key> <value>
2. ENV <key>=<value> ...

    二者的區別就是第一種是一次設置一個,第二種是一次設置多個。

例:

ENV MYSQL_VERSION 5.6 #設置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \   #使用常量
    && rm -rf /var/lib/apt/list/*
  • CMD關鍵字

    功能爲容器啓動時要運行的命令,語法有三種寫法

1. CMD ["executable","param1","param2"]
2. CMD ["param1","param2"]
3. CMD command param1 param2

    第三種比較好理解了,就時shell這種執行方式和寫法,第一種和第二種其實都是可執行文件加上參數的形式,舉例說明兩種寫法:

  • CMD [ "sh", "-c", "echo $HOME" 
  • CMD [ "echo", "$HOME" ]

    補充細節:這裏邊包括參數的必定要用雙引號,就是",不能是單引號。千萬不能寫成單引號,緣由是參數傳遞後,docker解析的是一個JSON array

    注意事項:

  •  容器啓動時默認執行的命令
  • 若是docker run 指定了其餘命令,CMD命令被忽略
  • 若是定義了多個CMD,只有最後一個會執行
  •     RUN & CMD

    不要把RUN和CMD搞混了。RUN是構件容器時就運行的命令以及提交運行結果,CMD是容器啓動時執行的命令,在構件時並不運行,構件時牢牢指定了這個命令究竟是個什麼樣子

  • ENTRYPOINT關鍵字

        功能是啓動時的默認命令,語法以下:

1. ENTRYPOINT ["executable", "param1", "param2"]
2. ENTRYPOINT command param1 param2

    與CMD比較說明(這倆命令太像了,並且還能夠配合使用):

    1. 相同點:

  • 只能寫一條,若是寫了多條,那麼只有最後一條生效

  • 容器啓動時才運行,運行時機相同

    2. 不一樣點:

  •  ENTRYPOINT不會被運行的command覆蓋,而CMD則會被覆蓋

  •  若是咱們在Dockerfile種同時寫了ENTRYPOINT和CMD,而且CMD指令不是一個完整的可執行命令,那麼CMD指定的內容將會做爲ENTRYPOINT的參數

  • shell格式:即把要運行的命令當作shell執行

RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

 

  • Exec格式:便是 命令,參數格式

RUN ["apt-get", "install", "-y", "vim"]
CMD ["/bin/echo", "hello docker"]
ENTRYPOINT ["/bin/echo", "hello docker"]

    例:如下兩個dockerfile結果相同

FROM centos  #指定基礎鏡像爲centos
EVN name Docker   #設定常量name 值爲Docker
ENTRYPOINT echo "hello $name"  #執行acho命令

 以上dockerfile生成的鏡像運行容器時輸出 hello Docker

FROM centos  #指定基礎鏡像爲centos
EVN name Docker   #設定常量name 值爲Docker
ENTRYPOINT ["/bin/echo", "hello $name"]  #執行acho命令

以上dockerfile生成的鏡像運行容器時輸出 hello $name,由於 ENTRYPOINT ["/bin/echo", "hello $name"] 指定容器啓動時運行的就是echo命令  不會識別$爲變量,作以下修改:

FROM centos  #指定基礎鏡像爲centos
EVN name Docker   #設定常量name 值爲Docker
ENTRYPOINT ["/bin/bash", "-c", "echo", "hello $name"]  #在shell中執行acho命令

容器啓動時輸出 hello Docker

相關文章
相關標籤/搜索