Dockfile介紹
從上到下依次執行 每次執行一條指令就創建一個鏡像層
第一條指令必須是FROM 表示需要構建的鏡像是由哪個鏡像為基礎鏡像 后續的指令運行於此基准鏡像所提供的運行環境
可以設置 .dockeringore 指定不打包進鏡像的文件列表
在docker build中執行的shell命令環境是由基礎鏡像所包含的命令集合
${ varriable:-default } 如果變量未設置值,則給變量賦一個默認值 ${ variable: +default } 如果已經給變量設置過值,則用default代替變量的值
COPY指令
從dockerfile的工作目錄中 復制指定文件到目標鏡像的文件系統中
COPY <src> ... <dest>
COPY ["<src>",... "<dest>"]
<dest>:目標路徑,即正在創建的image的文件系統路徑;建議為<dest>使用絕對路徑 否則,COPY指定則以WORKDIR為其起始路徑.
注意: 在路徑中有空白字符時,通常使用第二種格式
復制規則:
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>