天天看點

DOCKERFILE注意事項準則指令注意事項

盡量将Dockerfile放在空目錄中,如果目錄中必須有其他檔案,則使用.dockerignore檔案。

避免安裝不必須的包。

每個容器應該隻關注一個功能點。

最小化鏡像的層數。

多行參數時應該分類。這樣更清晰直白,便于閱讀和review,另外,在每個換行符\前都增加一個空格。

對建構緩存要有清楚的認識。

1. FROM必須是除了注釋以外的第一行;

2. 可以有多個FROM語句,來建立多個image;

RUN語句有兩種格式:

1. RUN

  盡量避免使用RUN apt-get upgrade或者dist-upgrade,因為基礎鏡像的很多核心包不會再未授權的容器中更新。

要結合RUN apt-get update和apt-get install在同一個RUN語句下一起使用。如:

  如果将update和install分開使用,執行多個Dockerfile時,會引起緩存問題,導緻後面執行的install語句會失敗。

另外,執行完apt-get語句後,最後最好加上删除安裝包的語句,以減小鏡像的體積。如:

  注意:官方的Debian和Ubuntu鏡像會自動執行“RUN apt-get clean”,是以不需要明确地删除指令。

  很多RUN指令都需要使用到管道,如:

  Docker使用/bin/sh -c解釋器來執行這些指令,該解釋器隻評估管道最後一個操作的傳回值來判斷整個指令是否成功。在上面的例子中,隻要wc -l指令成功了,即使wget指令失敗了,也會建立一個新鏡像。為了避免上述情況,可以在語句首部加上set -o pipefail &&。比如:

  注意:并非所有的shell都支援-o pipefail選項,比如說基于Debian的鏡像下的模式shell:dash shell。這種情況下,我們可以使用exec格式的RUN指令來顯示地選擇shell來支援pipefail選項。如:

CMD語句與RUN不同,RUN是在build鏡像的時候運作,而CMD語句是在build結束後運作。一個Dockerfile鐘可以有多個RUN語句,雖然也可以有多個CMD語句,但是卻隻有最後一條CMD語句會執行。CMD語句格式為:

EXPOSE指令指明容器會監聽連結的端口。是以,最好使用常用的、傳統的應用端口。比如,Apache web伺服器使用EXPOSE 80等。

為了給外部連結使用,你需要使用docker run指令來制定容器端口和host端口的映射。

用于設定環境變量,設定後,後面的RUM指令就可以使用之前的環境變量了。同時,還可以通過docker run --env key=value,在容器啟動時設定環境變量。如:

<a href="https://docs.docker.com/engine/reference/builder/#add">Dockerfile reference for the ADD instruction</a>

<a href="https://docs.docker.com/engine/reference/builder/#copy">Dockerfile reference for the COPY instruction</a>

雖然ADD和COPY功能相似,但一般來講,更建議使用COPY。因為COPY比ADD更透明,COPY隻支援從本地檔案到容器的拷貝,但是ADD還有一些其他不明顯的特性(比如本地tar包解壓縮和遠端URL支援)。是以,ADD的最優用處是本地tar包自動解壓縮到鏡像中。如:ADD rootfs.tar.xz /。

如果有多個Dockerfile步驟用于處理不同的檔案,建議分開COPY它們,而不是一次性拷貝。這可以保證每個步驟的build緩存隻在對應的檔案改變時才無效。比如:

  鏡像的大小很重要,是以不鼓勵使用ADD從遠端URL擷取包;可以使用curl或者wget來代替。這種方式你可以删除不再需要的檔案,如解壓縮後的tar包,進而不需要再添加額外的layer到鏡像中。比如,你應該避免這樣使用:

  而應該如此:

  對于不需要使用ADD指令tar包自動解壓縮功能的檔案和目錄,你應該總是使用COPY。

<a href="https://docs.docker.com/engine/reference/builder/#entrypoint">Dockerfile reference for the ENTRYPOINT instruction</a>

使用ENTRYPOINT來設定鏡像的主指令,就像這個鏡像運作時就是這條指令一樣(然後再使用CMD作為預設的flag)。

我們使用s3cmd指令作為鏡像的主指令。

<a href="https://docs.docker.com/engine/reference/builder/#volume">Dockerfile reference for the VOLUME instruction</a>

VOLUME指令一般用于資料庫的存儲區域,配置存儲,或者docker容器建立的檔案和目錄。

<a href="https://docs.docker.com/engine/reference/builder/#user">Dockerfile reference for the USER instruction</a>

如果服務可以在不需要特權的情況下運作,那麼就應該使用USER來切換使用者至非root使用者。可以用RUN指令建立使用者組和使用者如:

  應該避免安裝和使用sudo,因為它有不可預知的TTY和信号轉移特性,會産生很多問題。如果的确一定要使用類似sudo的功能(如root下初始化daemon,非root下運作),可以使用“gosu”。

<a href="https://docs.docker.com/engine/reference/builder/#workdir">Dockerfile reference for the WORKDIR instruction</a>

為了Dockerfile内容更加清晰和可靠,最好總是使用絕對路徑。同樣地,應該使用WORKDIR,而不是使用類似“cd … &amp;&amp; do-something”這樣的指令,因為那樣會導緻難以閱讀、查找錯誤和維護。

<a href="https://docs.docker.com/engine/reference/builder/#onbuild">Dockerfile reference for the ONBUILD instruction</a>

本文轉自 Mr_sheng 51CTO部落格,原文連結:http://blog.51cto.com/sf1314/2048114