1. 程式人生 > >docker學習之常用Dockerfile指令

docker學習之常用Dockerfile指令

今天我們學習幾個常用的Dockerfile指令,在 http://docs.docker.com/reference/builder/可以檢視Dockerfile中能使用的全部指令的清單。
一、CMD指令
CMD指令用於指定一個容器啟動時要執行的命令,這與RUN指令有點類似,但RUN指令是指定映象被構建時要執行的命令,而CMD指令是指定容器被啟動時要執行的命令,這與docker run命令執行容器時指定容器執行程式類似。

CMD ["/bin/bash"]
$ docker run -it ubuntu /bin/bash

上述兩條指令是等效的,實際上docker run命令是啟動容器時才指定執行的指令,而CMD指定的命令在構建映象時就已經確定,執行基於映象的容器,CMD指令指定的命令就會執行。
在CMD指令中也可以為要執行的命令指定引數:

CMD ["/bin/bash","-l"] 

docker run命令會覆蓋CMD命令,如果我們在Dockerfile裡指定了CMD指令,在建立容器的docker run命令中也指定了要執行的命令,這樣容器啟動後會執行docker run指定的命令,這樣看起來CMD指令就被docker run命令覆蓋了,另外一個值得注意的地方是:在Dockerfile中只能指定一條CMD命令,如果存在多條,只有最後一條CMD指令會起作用,如果想在容器啟動時執行多個程式,可以使用類似Supervisor這樣的服務管理工具。
二、ENTRYPOINT指令
ENTRYPOINT指令與CMD指令作用基本相同,二者的區別為:CMD指令會被docker run中指定的命令覆蓋,而ENTRYPOINT 指令指定的命令則不會被輕易覆蓋,實際上docker run命令中指定的的所有引數都會被當作引數再次傳遞給ENTRYPOINT指令。

 ENTRYPOINT ["/bin/bash"]
 ENTRYPOINT ["/bin/bash","-l"]

如果有需要,也可以覆蓋ENTRYPOINT指令,可以在docker run命令中指定 –entrypoint標誌覆蓋ENTRYPOINT指令。
三、WORKDIR指令
WORKDIR指令可以在建立容器時在容器內部指定一個工作目錄,ENTRYPOINT和CMD指令指定的程式會在這個目錄下執行。

 WORKDIR /opt/webapp/db
 RUN bundle install
 WORKDIR /opt/webapp/
 ENTRYPOINT ["rackup"]

先將工作目錄切換為 /opt/webapp/db執行bundle install命令,然後將工作目錄切換為/opt/webapp/,最後用ENTRYPOINT指令設定了啟動容器時執行的命令rackup。我們可以通過 -w選項在執行時覆蓋工作目錄:

 $ docker run -it -w /home/webappp/ ubuntu ls 

將/home/webappp/ 設為工作目錄。
四、ENV指令
ENV指令在構建映象中設定環境變數。
ENV RVM_PATH /home/rvm/
這個環境變數可以在後續RUN指令中使用,這就如同在命令前面指定了環境變數字首一樣:
RUN gem install apache 這個RUN指令會以下面的廣式執行:

RVM_PATH=/home/rvm/ gem install apache

我們也可以在其它指令中直接使用環境變數,與shell指令碼中使用變數的方法相同:’$變數名’。

 ENV TARGET_DIR /opt/app
 WORKDIR $TARGET_DIR

ENV指令設定的環境變數也會被注入從映象中建立的所有容器中。我們也可以在docker run命令中 使用-e選項向容器注入環境變數。
五、USER
USER指令用來指定映象以哪個使用者去執行

USER jix

指定映象啟動的容器以使用者jix的身份執行,我們可以在USER指令中指定UID或GID,或二者的組合。

 USER user
 USER user:group
 USER uid
 USER uid:gid
 USER user:gid
 USER uid:group

也可以在docker run 命令中通過-u選項指定使用者,注意docker run命令指定的使用者會覆蓋USER指令中設定的使用者。如果不指定使用者,則預設使用者為root。
六、VOLUME
VOLUME指令的作用是向基於映象建立的容器中添加捲,卷是存在一個或多個容器內的特定的目錄,可以提供以下功能:
.卷可以在容器間共享和重用。
.一個容器可以單獨擁有一個卷
.對卷的修改是立時生效的
.對卷的修改不會對更新映象產生影響
.卷會一直存在直到沒有任何容器再使用它
通過卷,我們可以將資料、資料庫、或者其它內容新增到映象,而不必將這些內容提交到映象,而且通過卷我們可以很方便地在多個容器間共享這些內容。下面來看一下VOLUME指令的使用:

 VOLUME ["/opt/project"]

這條指令將會為基於此映象建立的容器建立一個名為/opt/project的掛載點,我們也可以指定多個掛載點:

 VOLUME ["/opt/project","/data"]

七、ADD指令
ADD指令將構建環境下的檔案和目錄複製到映象中。

ADD index.html /opt/application/index.html

上面的指令會將構建目錄下的index.html複製到映象中的/opt/application/index.html,原始檔的位置引數可以是一個URL,或者構建上下文或構建環境中的檔案或或目錄,不能對構建環境目錄以外的檔案進行操作。 在ADD指令中,docker通過目的地址引數末尾的字元來判斷原始檔是目錄還是檔案。如果目的地址以’/’結尾,那麼docker就認為原始檔為目錄,如果目的地址不以’/’結尾,docker就認為原始檔是檔案。原始檔也可以使用網路上的資源:

 ADD http://wordpress.org/latest.zip /root/wordpress.zip

關於ADD指令最後一點要注意是:如果原始檔是gzip、bzip2、xz型別的歸檔檔案,docker會自動將其提取、解壓。

ADD apache.tar.gz /home/apache/

上面這條命令會將歸檔檔案apache.tar.gz解壓到映象/home/apache/目錄下。如果目的地址不存在的話,docker會
自動建立這個路徑,並且新建立的檔案和目錄的許可權為755,UID和GID都為0。
八、COPY指令
COPY指令與ADD指令類似,二者的區別是:COPY指令只是複製,不會提取和解壓gzip、bzip2、xz型別的歸檔檔案。
總結:
學習了dockerfile中常用的幾個命令,dockerfile中可以使用的命令遠遠不只這些,這些命令最好在實際應用中
學習、體會。