Dockerfile語法解析

Dockfile介紹

      從上到下依次執行 每次執行一條指令就建立一個鏡像層html

      第一條指令必須是FROM    表示須要構建的鏡像是由哪一個鏡像爲基礎鏡像   後續的指令運行於此基準鏡像所提供的運行環境 nginx

     能夠設置 .dockeringore 指定不打包進鏡像的文件列表web

     在docker build中執行的shell命令環境是由基礎鏡像所包含的命令集合docker

     ${ varriable:-default }  若是變量未設置值,則給變量賦一個默認值   ${ variable: +default } 若是已經給變量設置過值,則用default代替變量的值shell

 

   COPY指令數組

     從dockerfile的工做目錄中 複製指定文件到目標鏡像的文件系統中bash

     COPY <src> ... <dest> tcp

     COPY ["<src>",... "<dest>"] ide

     <dest>:目標路徑,即正在建立的image的文件系統路徑;建議爲<dest>使用絕對路徑   不然,COPY指定則以WORKDIR爲其起始路徑. ui

     注意:  在路徑中有空白字符時,一般使用第二種格式 

     複製規則:

          src的路徑不能是當前工做目錄之上的目錄或者文件 只能是工做目錄中的文件或者子目錄

          若是<src>是目錄,則其內部文件或子目錄會被遞歸複製,但<src>目錄自身不會被複制  至關於shell中的 cp  -r  /root/dir/*    /tmp

          若是指定了多個<src>或在<src>中使用了通配符  則<dest>必須是一個目錄,且必須以/結尾 

          若是<dest>事先不存在,它將會被自動建立,這包括其父目錄路徑

 

   ADD指令

        ADD指令相似於COPY指令    ADD支持使用TAR文件和URL路徑 

        若是<src>爲URL且<dest>不以/結尾,則<src>指定的文件將被下載並直接被 建立爲<dest>.若是<dest>以/結尾,則文件名URL指定的文件將被直接下載 並保存爲<dest>/<filename> 

      若是<src>是一個本地系統上的壓縮格式的tar文件,它將被展開爲一個目錄 ,其行爲相似於「tar -x」命令;然而,經過URL獲取到的tar文件將不會自動 展開 

     若是<src>有多個,或其間接或直接使用了通配符,則<dest>必須是一個以/結 尾的目錄路徑;若是<dest>不以/結尾,則其被視做一個普通文件,<src>的內 容將被直接寫入到<dest>

 

WORKDIR指令

    用於爲Dockerfile中全部的RUN、CMD、ENTRYPOINT、COPY和 ADD指定設定工做目錄

    在Dockerfile文件中,WORKDIR指令可出現屢次,其路徑也能夠爲相對路徑,不過 ,其是相對此前一個WORKDIR指令指定的路徑 

    另外 WORKDIR也可調用由ENV指定定義的變量 

 

VOLUME指令

    用於在image中建立一個掛載點目錄   以掛載Docker host上的卷或 其它容器上的卷 

    VOLUME <mountpoint> 或   VOLUME ["<mountpoint>"] 

    若是掛載點目錄路徑下此前在文件存在,  docker run命令會在卷掛載完成後將此前的全部文件複製到新掛載的卷中

   不能指定宿主機上面的目錄路徑  只能建立docker manage volume

 

 EXPOSE指令

    用於爲容器打開指定要監聽的端口以實現與外部通訊   動態綁定到宿主機的隨機端口  不能指定宿主機上的端口

    EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...]   EXPOSE指令可一次指定多個端口  EXPOSE 11211/udp 11211/tcp

    EXPOSE 只是表示當前鏡像在運行爲容器的時候能夠暴露指定的端口,可是須要在run的時候配合 -P 選項 不然即便在Dockerfile中

    經過EXPOSE指定的端口在容器運行的時候默認仍是不會被暴露的   EXPOSE 必定須要配合 -P 選項 才能發揮做用

 

ENV指令

     用於爲鏡像定義所需的環境變量,並可被Dockerfile文件中位於其後的其它指令(如ENV、ADD、COPY等)所調用

     ENV <key> <value> 

     ENV <key>=<value> ... 

     第二種格式可用一次設置多個變量,每一個變量爲一個"<key>=<value>"的 鍵值對.若是<value>中包含空格,能夠以反斜線(\)進行轉義,也可經過對<value>加引號進行標識.另外,反斜線也可用於續行

    在docker run的時候能夠經過 -e 選項直接覆蓋Dockerfile文件中已經指定的ENV或者添加爲容器新的ENV變量的

 

 RUN指令

    用於指定docker build過程當中運行的程序      其能夠是任何命令  可是須要基礎鏡像的shell環境的支持

    能夠出現屢次RUN指令

    RUN <command>       以shell的子進程運行

      <command>一般是一個shell命令,且以「/bin/sh -c」來運行它, 這意味着此進程在容器中的PID不爲1,不能接收Unix信號.所以,當使用 docker stop <container>命令中止容器時,此進程接收不到SIGTERM信號;可以接收信號的進程通常是進程號爲1的進程.

   RUN ["<executable>", "<param1>", "<param2>"]      直接由內核建立運行進程 可處理系統發送過來的信號 沒法調用shell中的變量

     參數是一個JSON格式的數組,其中<executable>爲要運行的 命令,後面的<paramN>爲傳遞給命令的選項或參數;然而,此種格式指定的命令不會以「/bin/sh -c」來發起,所以常見的shell操做如變量替換以及通配符(?,* 等)替換將不會進行;不過,若是要運行的命令依賴於此shell特性的話,能夠將其替換爲相似下面的格式

   RUN ["/bin/bash", "-c", "<executable>", "<param1>"]

    

CMD指令    

    CMD指令的首要目的在於爲啓動的容器指定默認要運行的程序,且其運行結束後,容器也將終止. 不過CMD指定的命令其能夠被docker run的命令行選項所覆蓋 

    CMD命令的執行時間週期 就是容器的生命週期 CMD一旦執行完畢  容器就會當即中止  CMD指令只有最後一個指令生效

    CMD指令通常不會單獨使用  一般都須要配合 ENTRYPOINT指令來設置

    CMD <command> 

    CMD [「<executable>」, 「<param1>」, 「<param2>」] 

    CMD ["<param1>","<param2>"]  爲ENTRYPOINT指令提供默認參數

    當執行docker run的時候能夠在最後添加自定義命令來覆蓋CMD中指定的命令

   

ENTRYPOINT指令

     主要用來指定shell的  把shell做爲容器中第一個啓動進程 經過接收CMD命令 把命令做爲參數啓動指定的子進程

     用來指定容器內核啓動的第一個進程 只有PID爲1的進程才能接收系統發送給容器的系統信號

     由ENTRYPOINT啓動的程序不會被docker run命 令行指定的參數所覆蓋.並且,這些命令行參數會被看成參數傳遞給ENTRYPOINT指定指定的程序 

     不過,docker run命令的--entrypoint選項的參數可覆蓋ENTRYPOINT指令指定的程序 

     docker run命令傳入的命令參數會覆蓋CMD指令的內容而且附加到 ENTRYPOINT命令最後作爲其參數使用 

 

   一個容器只是爲了運行單個程序

      每一個進程都應該是某個進程的子進程 除了init進程

     在shell中啓動的任何進程都是shell的子進程 意味着若是shell退出那麼在shell中啓動的進程都會被終止掉

     一個運行nginx的容器中nginx進程號必須爲1 不然因爲容器中的nginx進程沒法接收系統信號而沒法stop和kill掉正在運行的容器

     exec 頂替shell進程PID爲1 shell進程退出

 

USER指令

    用於指定運行image時的或運行Dockerfile中任何RUN、CMD或 ENTRYPOINT指令指定的程序時的用戶名或UID 

    默認狀況下container的運行身份爲root用戶 

    須要注意的是<UID>能夠爲任意數字 但實踐中其必須爲/etc/passwd中某用戶的有效UID  不然docker run命令將運行失敗

 

ONBUILD指令

    用於在Dockerfile中定義一個觸發器 

    Dockerfile用於build映像文件,此映像文件亦可做爲base image被另外一個Dockerfile用做FROM指令的參數,並以之構建新的映像文件

    在後面的這個Dockerfile中的FROM指令在build過程當中被執行時,將會「觸發」建立其base image的Dockerfile文件中的ONBUILD指令定義的觸發器 

 

HEALTHCHECK指令

     docker引擎斷定容器是否健康的機制是僅僅斷定容器是否處於運行狀態

     斷定運行的容器是否正常運行 並不能單一的檢測容器是否正在運行 須要更加具體化 須要檢測容器中的主進程是否能正常提供服務才行

     須要藉助外部命令檢測 如檢測nginx容器是否正常  可使用命令請求主頁 wget -O - -q a1f2903f6de3 獲取返回結果 進行健康檢查

   

ARG指令

   使用方法和ENV相同 可是隻能在docker build執行指令的時候生效 不能在docker run中生效 ENV在兩個執行階段都有效果

   使用ARG指令能夠用同一個Dockerfile 經過ARG的方式生成不一樣版本的鏡像   至關於給docker build命令傳遞變量參數

 

Dockerfile實例

[root@nginx-docker mynginx]# ls
Dockerfile  entrypoint.sh  index.html

[root@nginx-docker mynginx]# vi Dockerfile 

FROM nginx:1.14-alpine
LABEL maintainer="yxh"

RUN mkdir -p /data/web/html
ENV NGX_DOC_ROOT='/data/web/html/'
ADD entrypoint.sh /bin
ADD index.html ${NGX_DOC_ROOT}

EXPOSE 80 8080
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]



[root@nginx-docker mynginx]# vi entrypoint.sh 

#!/bin/sh

cat > /etc/nginx/conf.d/www.conf << EOF
server
{
   server_name $HOSTNAME;
   listen ${IP:-0.0.0.0}:${PORT:-80};
   root $NGX_DOC_ROOT;
}
EOF

exec "$@"


######調試容器##########
[root@nginx-docker mynginx]# docker run --name nginx1 -it nginx:1.14-alpine

nginx1默認啓動的不是/bin/sh 因此即便使用-it 選項也沒法進入容器
[root@nginx-docker mynginx]# docker run --name nginx1 -it nginx:1.14-alpine /bin/sh
/ # ifconfig
若是要進入交互式容器須要在最後添加啓動命令 /bin/sh來覆蓋CMD命令
這樣就能夠進入容器
/ # ps aux
PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh
    6 root       0:00 ps aux

調試容器步驟 不管什麼容器均可以採起這種方式
  docker run --name myweb1 --rm -it myweb:v0.1-1 /bin/sh
  docker exec -it  myweb1 /bin/sh 進入已經運行的容器 

/usr/sbin # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN

/data # wget -O - -q a1f2903f6de3
<h1> my nginx index page </h1>
/data #

有環境變量的最大好處在docker run的時候能夠直接根據變量生成各類
應用程序的配置文件
定義應用程序的配置文件的時候就只須要調用變量名稱便可
docker run -e "HOSTNAME=yxh" --name yxhweb myweb2:v1.1

/ # vi /etc/hosts
/ # wget -O - -q  yxh
<h1> my nginx index page </h1>
Dockerfile實例
相關文章
相關標籤/搜索