Dockerfile詳解及優化


 Dockerfile詳解

0. Dockerfile的作用

docker可以根據Dockerfile中的指令來構建docker鏡像。Dockerfile是一個文本文件,其應當包含用戶想要構建一個鏡像的所有指令。

1. 構建鏡像的流程

真正執行構建任務的(就是讀取Dockerfile中的指令構建新的鏡像)是docker deamon。

  1. 執行  docker build -t images-name:tag . 
  2. docker client會先將 當前目錄下的所有文件遞歸的發送給docker deamon
  3. docker deamon檢查Dockerfile是否有有語法錯誤,有錯誤則停止構建並將錯誤發送給docker client,沒有錯誤繼續執行
  4. docker deamon根據Dockerfile中的指令,一行一行的進行鏡像的構建
  5. 構建成功后,docker deamon自動清理context.

1. Dockerfile支持的指令

  • FROM  <image>[:tag]   #代表着一個新的build stage的開始,並確定這個build是基於哪個鏡像來構建新的鏡像,在所有的指令中只有這個是必須要有的。
  • ENV <key>=<value> | <key> <value>  #配置環境變量,注意此配置會在container中生效。前一種可以一行聲明多個環境變量,后一種一行一個。
  • ARG <key>[=<value>]  #變量,此變量的聲明周期與dockerfile構建過程一致,不會在container中生效。可以通過build時添加--build-arg <key>=<value>進行覆蓋。注意:ARG時唯一可以放到FROM之前的指令,當ARG放到FROM之前時,它的作用於只到FROM這一行。
  • COPY src dest # 將src代表的文件或者文件夾拷貝到dest代表的目錄下。src支持通配符* ?
  • ADD src dest #將src代表的文件或者文件夾或者網絡資源 拷貝到 dest代表的base-image的目錄下。src支持通配符 * ?
  • RUN command  #docker deamon在構建新的鏡像時,是通過先基於FROM的鏡像開啟一個container,然后在這個container里執行。RUN指令就是是你想在container中執行的command。
  • ENTRYPOINT ["executable", "param1", "param2"] | command param1 param2 # 將鏡像變成一個executable。推薦用CMD來代替。
  • CMD ["executable", "param1", "parama2"] | ["param1", "param2"] | command param1 param2 # 最后有一個CMD指令才有效,它代表這個image被用來創建container成功后執行的命令。第二種形式需要個ENTRYPOINT指令結合使用。
  • LABEL <key>=<value> <key>=<value> #代表着這個image的元信息,比如此image的描述,版本,作者信息等等。
  • EXPOSE port[/protocol] #通過這個image啟動的container將會監聽這些端口。但是注意這個只是在container內部監聽的端口,當你想通過主機訪問時需要在啟動container時用-p這進行映射。
  • USER <user>[:<group>] | <UID>[:<GID>] #在這個指令之后的操作,以及運行container時,指定為此用戶。
  • WORKDIR /path #在此指令之后的操作,以及container的默認進入路徑都將時 /path目錄。
  • VOLUME ['/path1', '/path2'] #基於此鏡像創建的container都將擁有VOLUME中指定的掛在目錄。注意映射的主機目錄無法指定,有docker deamon自動生成,可以通過docker inspect查看Mounts屬性。

2. Dockerfile編寫優化

  1. 一個docker image只負責一個職責。當有多個服務時,請將服務分別docker化,然后組合使用這些docker images。

  2. 就像編程一樣,當一個字符串出現多次時,請用ARG來聲明變量取代hard code。

  3. 拷貝文件到鏡像時,ADD負責網絡資源的拷貝,COPY負責本地文件的COPY。

  4. 盡量使用cache,docker在build鏡像時可以利用緩存,緩存的原則時:當重復構建時,如果單個指令的內容沒有變化,則docker會默認使用cache。

  5. 將相同變化頻率的RUN指令合並成一個。注意,一定要是相同變化頻率的RUN命令才能合並成一個,不然緩存的特性就無法使用了。

  6. 合理使用.dockerignore,減少images的體積。

  7. 盡量使用CMD,VOLUME將image進行服務化。

  8. 使用LABEL對image進行元信息的描述。

  9. 單一服務的基礎鏡像如何可以請使用alpine版本的鏡像來減少image的體積。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM