Docker入門實戰(三)——用Dockerfile構建映象
在Docker中,構建一個自定義映象共有兩種方法,一是通過commit指令構建,二是通過Dockerfile檔案構建。第一種方式在上篇部落格中已經詳細介紹(Docker入門實戰(二)——Docker映象操作),接下來介紹在Docker中更為常用的方法——使用Dockerfile構建映象。
用Dockerfile構建映象的基本流程
先來回顧下commit方式建立映象的流程:
1. 首先需要有一個基礎映象(可以把基礎映象理解為作業系統)
2. 然後基於該映象建立容器
3. 在容器中配置執行環境
4. 最後使用docker commit命令將容器打包成映象
上述過程的第三步主要任務是在容器中安裝軟體,並進行相應的配置,如果把這個過程所要執行的命令全都提取出來,寫入一個檔案中,若需要構建映象則直接執行該檔案,基於其中的命令生成一個映象。這就是基於Dockerfile構建映象的方式,這個檔案就稱為Dockerfile。
Dockerfile檔案的構成
Dockerfile檔案一共分為四個部分,分別是:註釋資訊、基礎映象、建立者資訊、構建映象所需的命令,如下所示:
# Version: 1.1 #版本資訊
FROM centos:7.2 #基礎映象
MAINTAINER Chaimm "[email protected]" #維護者資訊
RUN …… #以下為命令區
CMD ……
EXPOSE ……
該Dockerfile被構建時,Docker會生成一個具有指定基礎映象的作業系統,並逐一執行命令區的命令。當命令命令執行結束後,一個你所需要的映象便生成了。
Dockerfile指令
RUN
RUN的用法
RUN後面跟構建時需要執行的命令,有兩種寫法:
1.方式一:RUN後直接跟命令
RUN 命令 -引數
2.方式二:命令和引數以陣列的形式存放(推薦)
RUN ["命令","引數"]
RUN的特點
- RUN在映象被構建時執行,因此RUN後一般跟用於構建映象的命令,如安裝軟體的命令、環境配置的命令等。
- RUN可以有多條,在構建映象時被依次執行。
CMD
CMD的用法
CMD後的命令僅在容器啟動時執行,和RUN一樣,也有兩種用法:
1.方式一:CMD後直接跟命令
CMD 命令 -引數
2.方式二:命令和引數以陣列的形式存放(推薦)
CMD ["命令","引數"]
CMD的特點
- CMD在容器執行的時候執行,而且一個Dockerfile中該命令只能有1個或0個,因此CMD後一般跟用於啟動軟體的命令。
- CMD會被docker run末尾的命令覆蓋。
PS:docker run的末尾的命令也在容器啟動的時候執行,而且它的優先順序較高,會覆蓋Dockerfile中的CMD命令。
ENTRYPOINT
和CMD一樣,ENTRYPOINT也在容器啟動時執行,只不過ENTRYPOINT不會被docker run後的命令覆蓋。當容器執行時,docker run後的命令會追加到ENTRYPOINT的末尾,因此ENTRYPOINT和docker run搭配可以產生神奇的效果:
- 在Dockerfile的ENTRYPOINT後僅提供命令:
ENTRYPOINT ["/usr/sbin/nginx"]
- 在docker run末尾僅提供引數:
docker run -i -t myContainer -g "daemon off;"
此時,docker run某位的引數會追加到ENTRYPOINT後,從而相當於執行命令:
/usr/sbin/nginx -g "daemon off;"
這種方式可以為命令動態新增引數。
WORKDIR
該命令用於指定Dockerfile中指令的工作目錄,類似於Linux中的cd命令。如:
WORKDIR /usr/tomcat/bin
ENTRYPOINT ["startup.sh"]
當設定完WORKDIR後,後面的命令將基於該工作目錄執行。
ENV
該命令用於設定環境變數,且該環境變數會持久化地儲存至該映象的所有容器中。
ENV CATALINA_HOME /usr/tomcat/bin/ #定義環境變數
WORKDIR $CATALINA_HOME #使用環境變數
也可以使用-E引數在容器執行的時候設定,如下所示:
run -i -t -e "CATALINA_HOME=/usr/tomcat/bin/" myContainer /bin/bash
使用-E引數設定的環境變數只在當前容器執行期間有效,關閉容器後隨即消失。
USER
該命令用於指定映象啟動時的使用者身份和使用者組,如:
USER chai #指定使用者
USER chai:group #指定使用者和使用者組
VOLUME
該命令用於為基於本映象的容器添加捲。
什麼是“卷”?
“卷”本質上是一個目錄,該目錄存在於宿主機中,可以在多個容器間共享。
如何新增“卷”?
VOLUME ["目錄"]
ADD
該命令用於將宿主機中的檔案/目錄複製到容器的指定目錄下,如:
COPY file /usr/bin/ #將構建目錄中的file檔案複製到容器的/usr/bin目錄下
COPY file /usr/bin/newFile #將file檔案複製到容器的/usr/bin目錄下,並賦予新的檔名
PS:Docker根據末尾是否有“/”來判斷目標路徑為目錄還是檔案。
COPY
本命令和ADD類似,唯一區別是ADD可以新增宿主機中任何檔案/目錄,而COPY只能添加當前構建目錄中的檔案/目錄。
生成映象
當Dockerfile書寫完畢後,使用如下命令生成映象:
docker build -t="使用者名稱/映象倉庫名:版本號" dockerfile路徑
啟動映象
當映象構件完畢後,使用以下命令來啟動一個映象(啟動後即為一個容器):
docker run --name 容器名 -p 8080:80 -it 映象名 /bin/bash
關於docker run命令可以參考博文Docker入門實戰(一)——Docker常用命令,這裡詳細介紹-p引數。
-p引數用於指定docker容器埠和宿主機埠的對映關係,這樣就能通過訪問宿主機埠號來訪問容器。一共有三種表示方式:
1. -p 宿主機埠號:容器埠號
將容器的指定埠號繫結到宿主機的指定埠號上。
2. -p 容器埠號
這裡省略宿主機埠號後,docker會從49000~49900內隨機選一個作為宿主機埠號。
3. -p 宿主機IP:宿主機埠號:容器埠號
若宿主機擁有多個IP,則需指定具體IP。
此外,這裡宿主機埠號也可以省略,如-p 127.0.0.1::80
PS:除了 -p引數外還有個-P引數,該引數後無需跟埠號,它會將dockerfile中指定的埠號繫結到宿主機的隨機埠號上。