從上到下依次執行 每次執行一條指令就建立一個鏡像層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>