咱們前面的篇章講過,咱們從docker hub或其餘docker站點下載的鏡像通常不會符合咱們的需求,因此咱們須要製做合適咱們自身的鏡像,而製做鏡像的方式有兩種,一是基於現有的容器建立,二是基於DockerFile建立。
DockerFile是構建docker鏡像的源碼,是一個純文本文件,以「#」號開頭的是註釋信息,剩下的爲須要指定的命令,命令不區分大小寫,可是建議使用大寫,命令爲順序執行。但,第一個命令必須爲‘FROM’開頭,它表示製做該鏡像必須以哪一個鏡像爲基礎鏡像。格式以下(在當前目錄,cat Dockerfile):html
#test image
FROM nginx:1.10.2
ENV DOC_ROOT /usr/share/nginx/html/
LABEL "MAINTAINER"="lidf <lidf@wuaking.com>"
COPY index.html ${DOC_ROOT:-/usr/share/nginx/html/}
WORKDIR /data/nginx1/
ADD nginx-1.10.3.tar.gz ./
#ADD http://nginx.org/download/nginx-1.10.3.tar.gz /data/nginx2/
WORKDIR /data/nginx2/
COPY ps /bin/
COPY curl /bin/
COPY libprocps.so.4 /usr/local/lib/
COPY libcurl.so.4 /usr/local/lib/
COPY libssl3.so /usr/local/lib/
COPY libsmime3.so /usr/local/lib/
COPY libnss3.so /usr/local/lib/
COPY libnssutil3.so /usr/local/lib/
RUN ldconfig
#RUN mkdir -p /data/nginx3/ && tar -xf nginx-1.10.3.tar.gz -C /data/nginx3/
VOLUME /data/mysql/
EXPOSE 80/tcp
#CMD ["nginx","-g","daemon off;"]
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD touch /tmp1/aa || exit 1
CMD nginx -g "daemon off;"mysql
上面的示例文件中: 以"#"號打頭的爲註釋信息,FROM通常爲第一個指令,表示以什麼鏡像做爲基礎鏡像linux
ENV
用於爲鏡像定義所需的環境變量,並可被Dockerfile文件中位於其後的其餘指令(如ENV、ADD、COPY等)所調用
調用格式爲$variable_name或${variable_name}
語法
ENV <key> <value>或
ENV <key>=<value> ...
第一種格式中,<key>以後的全部內容均會被視做其<value>的組成部分,所以,一次只能設置一個變量
第二種格式可一次設置多個變量,每一個變量爲一個"<key>=<value>"的鍵值對,若是<value>中包含空格,能夠以反斜線\進行轉義,有能夠經過對<value>加引號進行標識;另外,反斜線也可用於續行;
定義多個變量時,建議使用第二種方式,以便在同一層中完成全部功能nginx
LABEL
用於添加描述鏡像的元數據信息
語法:
LABEL <key>=<value> <key>=<value>
LABEL描述信息是鍵值對,若是須要在標籤的值中包含空格,須要使用引號和反斜槓,一個鏡像能夠包含多個標籤,多個標籤能夠在一行中指定web
COPY
用於從Docker宿主機複製文件到新建的鏡像文件中
語法:
COPY <src>...<dest> 或
COPY ["<src>",... "<dest>"]
<src>:要複製的源文件或目錄,支持通配符
<dest>:目標路徑,即正在建立的image的文件系統路徑;建議爲<dest>使用絕對路徑,不然,COPY指定則以WORKDIR爲其其實路徑;
注意:在路徑中有空白字符時,一般使用第二種格式
文件複製準則
<src>必須是build上下文中的路徑,不能是其父目錄中的文件
若是<src>是目錄,則其內部文件或子目錄會被遞歸複製,但<src>目錄自身不會被複制
若是指定了多個<src>,或在<src>中使用了通配符,則<dest>必須是一個目錄,且必須以/結尾
若是<dest>實現不存在,他將會被自動建立,這包括其父目錄路徑sql
WORKDIR
用於爲Dockerfile中全部的RUN、CMD、ENTRYPOINT\COPY和ADD設定工做目錄
語法
WORKDIR <dirpath>
在Dockerfile文件中,WORKDIR指令可 出現屢次,其路徑也能夠爲相對路徑,不過,其是相對此前一個WORKDIR指令指定的相對路徑
另外,WORKDIR也可調用有ENV指定定義的變量
例如
WORKDIR /var/log
WORKDIR $STATEPATHdocker
ADD
ADD命令指令相似與COPY指令,ADD支持使用TAR文件和URL路徑
語法
ADD <src>... <dest> 或
ADD ["<src>",... "<dest>"]
操做準則
同COPY命令
若是<src>爲URL且<dest>不以/結尾,則<src>指定的文件將被下載並直接被建立爲<dest>;若是<dest>以/結尾,則文件名URL指定的文件將被直接西在並保存爲<dest>/<filename>
若是<src>是一個本地系統上的壓縮格式的tar文件,他將被展開爲一個目錄,其行爲相似於"tar -x"命令;然而,經過URL獲取到的tar文件將不會被自動展開;
若是<src>有多個,或其簡介或直接使用了通配符,則<dest>必須是一個以/結尾的目錄路徑;若是<dest>不以/結尾,則其被視做一個普通文件,<src>的內容將被直接寫入到<dest>shell
VOLUME
用於在image中建立一個掛載點目錄,以掛載Docker host上的卷或其餘容器上的卷
語法:
VOLUME <mountpoint> 或
VOLUME ["<mountpoint>"]
若是掛載點目錄路徑下此前在文件存在文件,docker run命令會在卷掛載完成後將此前的全部的文件複製到新掛載的卷中json
EXPOSE
用於爲容器打開指定要監聽的端口以實現與外部通訊
語法
EXPOSE <port>[/<protocol>][<port>[/<protocol>]]
EXPOSE指令可一次指定多個端口,例如
EXPOSE 11211/udp 11211/tcp數組
RUN
用於指定docker build過程當中運行的程序,能夠是任何命令,但必須是基礎鏡像中有的命令
語法
RUN <command> 或
RUN ["<executable>","<param1>","<param2>"]
第一種格式中,<command>一般是一個shell命令,且以"/bin/sh -c"來運行他,這意味着此進程在容器中的PID不爲1,不能直接接受Unix信號,所以,當使用doker stop <container>命令來中止容器時,此進程接受不到SIGTERM信號;
第二種語法格式中的參數是一個JSON格式的數組,其中<executable>爲要運行的命令,後面的<paramN>爲傳遞給命令的選項或參數;然而,此種格式指定的命令不會以"/bin/sh -c"來發起,所以常見的shell操做如變量替換以及通配符替換\管道\輸入輸出重定向等shell的特性將不會進行;不過,若是要運行的命令依賴與此shell特性的話,能夠將其替換爲下面的格式。
RUN ["/bin/bash","-c","<executable>","<param1>"]
json數組中,要使用雙引號
CMD
相似RUN指令,CMD指令也可用於運行任何命令或應用程序,不過兩者的運行時間點不一樣
RUN指令運行於映像文件構建過程當中,而CMD指令運行於基於Dockerfile構建出的新映像文件啓動一個容器時
CMD指令的首要目的在於爲啓動的容器指定默認要運行的程序,且運行結束後,容器也將終止;不過,CMD指定的命令其能夠被docker run的命令行選項所覆蓋
在Dockerfile中能夠存在多個CMD指令,但僅最後一個會生效
語法
CMD <command> 或
CMD ["<executable>","<param1>","<param2>"]
CMD ["<param1>","<param2>"]
前兩種語法格式的意義同RUN
第三種則用於爲ENTRYPOINT指令提供默認參數
ENTRYPOINT
相似CMD指令的功能,用於爲容器指定默認運行程序,從而使得容器像是一個單獨的可執行程序
於CMD不一樣的是,由ENTRYPOINT啓動的程序不會被docker run命令行指定的參數所覆蓋,並且,這些命令行參數會被當作參數傳遞給ENTRYPOINT指定的程序,不過,docker run命令的--entrypoint選項的參數可覆蓋ENTRYPOINT指令指定的程序
在Dockerfile中,若是同時出現CMD和ENTRYPOINT,則CMD後的指令會被當作ENTRYPOINT的參數
此命令主要爲傳遞環境變量做用
語法
ENTRYPOINT <command>
ENTRYPOINT ["<executable>","<param1>","<param2>"]
docker run命令傳入的命令參數會覆蓋CMD指令的內容而且福加到ENTRYPOINT命令最後做爲其參數使用
Dockerfile文件中也能夠存在多個ENTRYPOINT指令,但僅有最有一個生效
USER
用於指定運行image時的或運行Dockerfile中任何RUN\CMD或ENTRYPOINT指令的程序時的用戶名或UID
默認狀況下,container的運行身份爲root用戶
語法
USER <UID>|<UserName>
須要注意的是,<UID>可爲任意數字,但實踐中必須爲容器中/etc/passwd中某用戶的有效UID,不然,docker run命令將運行失敗
HEALTHCHECK
healtcheck定義如何監測容器是否還在工做
他能夠監測web服務的假死狀態,好比已經訪問不到服務了,可是web進程仍在運行
語法
HEALTHCHECK [OPTION] CMD command(在容器內部運行一共命令來檢測)
HEALTHCHECK NONE(不作監控狀態監測)
選項
--interval=DURATION(default:30s)
--timeout=DURATION(default:30s)
--start-period=DURATION(default:30s)#容器啓動後多久開始執行健康狀態監測
--retries=N(default:3)
執行命令有三種狀態
0:成功
1:不健康
2:保留項(不要使用這個狀態碼)
例:
HEALTHCHECK --interval=5m --timeout=3s CMD cutl -f http://localhost/ || exit 1
docker inspect --format='{{json .State.Health}}' containerName 查看健康監測狀態
SHELL
定義默認的shell
linux 默認shell爲["/bin/sh","-c"],windowns爲["cmd","/S","/C"]
瞭解了以上命令,就能夠開始作鏡像了,作鏡像的命令爲 docker build -t TagName ./
擴展:ENTRYPOINT實例
[root@localhost img3]# cat Dockerfile
FROM nginx:1.10.2
ENV DOC_ROOT="/data/web/html"
ADD entrypoint.sh /bin/
ADD index.html /data/web/html/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
[root@localhost img3]# cat entrypoint.sh
#!/bin/shcat > /etc/nginx/conf.d/www.conf << EOFserver{server_name $HOSTNAME;listen ${IP:-0.0.0.0}:${PORT:-80} default;root ${DOC_ROOT:-/usr/share/nginx/html};}EOFexec "$@"以上兩個文本展現了entrypoint的使用方式,首先咱們定義了entrypoint.sh這個腳本,這個腳本最關鍵的在最後一句,上面已經說過,在一個Dockerfile中,若是同時出現DENTRYPOINT和CMD,則CMD後的命令做爲ENTRYPOINT的參數,在entrypoint.sh腳本中,最後一句exec表明使用後面的命令頂替當前的命令稱爲進程號爲1的進程, $@ 就表明cmd後的全部參數.