docker之Dockerfile指令介紹

wadeson發表於2017-11-01
Docker通過對於在Dockerfile中的一系列指令的順序解析實現自動的image的構建
  通過使用build命令,根據Dockerfiel的描述來構建映象
  通過原始碼路徑的方式
  通過標準輸入流的方式
 
通過原始碼路徑
  Dockerfile需要放置在專案的根目錄位置
  在構建的時候,Dockerfile client會把整個context打包傳送到Docker Server端,然後由server端負責build映象,在構建成功後,會刪除context目錄
  docker build -t {映象名字} {專案路徑可以是相對路徑}

  docker利用Dockerfile來構建新映象之前,先來了解一下Dockerfile建立中使用到的指令

通過標準輸入流:

  通過標準輸入流的方式獲取Dockerfile的內容
  client不會打包上傳context目錄,因此對於一些ADD、COPY等涉及host本地檔案複製的操作不能夠支援
  docker build -t {映象名字} - < Dockerfile路徑
 
build cache:
  Dockerfile中的每一個指令執行完畢後,都會提交為一個image,這樣保證了指令之間不會有影響
  Dockerfile會盡可能嘗試重用之前已經構建的映象
  可以通過在build命令中增加--no-cache的方式來禁用這個cache
 
Dockerfile指令:
  只支援Docker自己定義的一套指令,不支援自定義
  大小寫不敏感,但是建議全部使用大寫
  根據Dockerfile的內容順序執行
 
FROM:
  FROM {base映象}
  必須放在DOckerfile的第一行,表示從哪個baseimage開始構建
 
MAINTAINER:
  可選的,用來標識image作者的地方
 
RUN:
  每一個RUN指令都會是在一個新的container裡面執行,並提交為一個image作為下一個RUN的base
  一個Dockerfile中可以包含多個RUN,按定義順序執行
  RUN支援兩種執行方式:
    RUN <cmd> 這個會當作/bin/sh -c “cmd” 執行
    RUN [“executable”,“arg1”,。。],Docker把他當作json的順序來解析,因此必須使用雙引號,而且executable需要是完整路徑
 
  RUN 都是啟動一個容器、執行命令、然後提交儲存層檔案變更。第一層 RUN command1 的執行僅僅是當前程式,一個記憶體上的變化而已,其結果不會造成任何檔案。而到第二層的時候,啟動的是一個全新的容器,跟第一層的容器更完全沒關係,自然不可能繼承前一層構建過程中的記憶體變化。而如果需要將兩條命令或者多條命令聯合起來執行需要加上&&。如:cd /usr/local/src && wget xxxxxxx
 
CMD:
  CMD的作用是作為執行container時候的預設行為(容器預設的啟動命令)
  當執行container的時候宣告瞭command,則不再用image中的CMD預設所定義的命令
  一個Dockerfile中只能有一個有效的CMD,當定義多個CMD的時候,只有最後一個才會起作用
 
CMD定義的三種方式:
  CMD <cmd> 這個會當作/bin/sh -c "cmd"來執行
  CMD ["executable","arg1",....]
  CMD ["arg1","arg2"],這個時候CMD作為ENTRYPOINT的引數
 

EXPOSE 宣告埠

  格式為 EXPOSE <埠1> [<埠2>...]

  EXPOSE 指令是宣告執行時容器提供服務埠,這只是一個宣告,在執行時並不會因為這個宣告應用就會開啟這個埠的服務。在 Dockerfile 中寫入這樣的宣告有兩個好處,一個是幫助映象使用者理解這個映象服務的守護埠,以方便配置對映;另一個用處則是在執行時使用隨機埠對映時,也就是 docker run -P 時,會自動隨機對映 EXPOSE 的埠。

 
entrypoint:
  entrypoint的作用是,把整個container變成了一個可執行的檔案,這樣不能夠通過替換CMD的方法來改變建立container的方式。但是可以通過引數傳遞的方法影響到container內部
  每個Dockerfile只能夠包含一個entrypoint,多個entrypoint只有最後一個有效
  當定義了entrypoint以後,CMD只能夠作為引數進行傳遞
 
entrypoint定義方式:
  entrypoint ["executable","arg1","arg2"],這種定義方式下,CMD可以通過json的方式來定義entrypoint的引數,可以通過在執行container的時候通過指定command的方式傳遞引數
  entrypoint <cmd>,當作/bin/bash -c "cmd"執行命令
 
ADD & COPY:
  當在原始碼構建的方式下,可以通過ADD和COPY的方式,把host上的檔案或者目錄複製到image中
  ADD和COPY的源必須在context路徑下
  當src為網路URL的情況下,ADD指令可以把它下載到dest的指定位置,這個在任何build的方式下都可以work
  ADD相對COPY還有一個多的功能,能夠進行自動解壓壓縮包
 
ENV:
  ENV key value
  用來設定環境變數,後續的RUN可以使用它所建立的環境變數
  當建立基於該映象的container的時候,會自動擁有設定的環境變數
 
WORKDIR:
  用來指定當前工作目錄(或者稱為當前目錄)
  當使用相對目錄的情況下,採用上一個WORKDIR指定的目錄作為基準
 
USER:
  指定UID或者username,來決定執行RUN指令的使用者
 
ONBUILD:
  ONBUILD作為一個trigger的標記,可以用來trigger任何Dockerfile中的指令
  可以定義多個ONBUILD指令
  當下一個映象B使用映象A作為base的時候,在FROM A指令前,會先按照順序執行在構建A時候定義的ONBUILD指令
  ONBUILD <DOCKERFILE 指令> <content>
 
VOLUME:
  用來建立一個在image之外的mount point,用來在多個container之間實現資料共享
  執行使用json array的方式定義多個volume
  VOLUME ["/var/data1","/var/data2"]
  或者plain text的情況下定義多個VOLUME指令

相關文章