Dockerfile注意事項

準則

  1. 儘可能將Dockerfile放在空目錄中,若是目錄中必須有其餘文件,則使用.dockerignore文件。
  2. 避免安裝沒必要須的包。
  3. 每一個容器應該只關注一個功能點。
  4. 最小化鏡像的層數。
  5. 多行參數時應該分類。這樣更清晰直白,便於閱讀和review,另外,在每一個換行符\前都增長一個空格。
  6. 對構建緩存要有清楚的認識。

指令注意事項

FROM

    Dockerfile reference for the FROM instruction
  任什麼時候候,儘可能使用官方鏡像源做爲你鏡像的基礎鏡像。咱們建議使用Debian Image,由於其被很好地管理着,而且做爲一個完整的發佈包,但體積卻保持着最小化(當前不足150MB)。
  1. FROM必須是除了註釋之外的第一行;
  2. 能夠有多個FROM語句,來建立多個image;
  3.html

LABEL

  Dockerfile reference for the LABEL instructiongit

RUN

  Dockerfile reference for the RUN instruction
  RUN語句有兩種格式:
1. RUNgithub

apt-get

  儘可能避免使用RUN apt-get upgrade或者dist-upgrade,由於基礎鏡像的不少核心包不會再未受權的容器中升級。
  要結合RUN apt-get update和apt-get install在同一個RUN語句下一塊兒使用。如:web

RUN apt-get update && apt-get install -y \
        package-bar \
        package-baz \
        package-foo

  若是將update和install分開使用,執行多個Dockerfile時,會引發緩存問題,致使後面執行的install語句會失敗。
  另外,執行完apt-get語句後,最後最好加上刪除安裝包的語句,以減少鏡像的體積。如:docker

RUN apt-get update && apt-get install -y \
    aufs-tools \
    automake \
    build-essential \
 && rm -rf /var/lib/apt/lists/*

  注意:官方的Debian和Ubuntu鏡像會自動執行「RUN apt-get clean」,因此不須要明確地刪除指令。shell

管道使用

  不少RUN命令都須要使用到管道,如:數據庫

RUN wget -O - https://some.site | wc -l > /number

  Docker使用/bin/sh -c解釋器來執行這些命令,該解釋器只評估管道最後一個操做的返回值來判斷整個命令是否成功。在上面的例子中,只要wc -l命令成功了,即便wget命令失敗了,也會建立一個新鏡像。爲了不上述狀況,能夠在語句首部加上set -o pipefail &&。好比:緩存

RUN set -o pipefail && wget -O - https://some.site | wc -l > /number

  注意:並不是全部的shell都支持-o pipefail選項,好比說基於Debian的鏡像下的模式shell:dash shell。這種狀況下,咱們可使用exec格式的RUN命令來顯示地選擇shell來支持pipefail選項。如:bash

RUN ["/bin/bash", "-c", "set -o pipefail && wget -O - https://some.site | wc -l > /number"]

CMD

  Dockerfile reference for the CMD instruction
  CMD語句與RUN不一樣,RUN是在build鏡像的時候運行,而CMD語句是在build結束後運行。一個Dockerfile鍾能夠有多個RUN語句,雖然也能夠有多個CMD語句,可是卻只有最後一條CMD語句會執行。CMD語句格式爲:服務器

CMD [「executable」, 「param1」, 「param2」…]

EXPOSE

  Dockerfile reference for the EXPOSE instruction
  EXPOSE指令指明容器會監聽連接的端口。所以,最好使用經常使用的、傳統的應用端口。好比,Apache web服務器使用EXPOSE 80等。
  爲了給外部連接使用,你須要使用docker run命令來制定容器端口和host端口的映射。

ENV

  Dockerfile reference for the ENV instruction
  用於設置環境變量,設置後,後面的RUM指令就可使用以前的環境變量了。同時,還能夠經過docker run --env key=value,在容器啓動時設置環境變量。如:

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

ADD和COPY

Dockerfile reference for the ADD instruction
Dockerfile reference for the COPY instruction
  雖然ADD和COPY功能類似,但通常來說,更建議使用COPY。由於COPY比ADD更透明,COPY只支持從本地文件到容器的拷貝,可是ADD還有一些其餘不明顯的特性(好比本地tar包解壓縮和遠程URL支持)。所以,ADD的最優用處是本地tar包自動解壓縮到鏡像中。如:ADD rootfs.tar.xz /。
  若是有多個Dockerfile步驟用於處理不一樣的文件,建議分開COPY它們,而不是一次性拷貝。這能夠保證每一個步驟的build緩存只在對應的文件改變時才無效。好比:

COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
COPY . /tmp/

  鏡像的大小很重要,所以不鼓勵使用ADD從遠端URL獲取包;可使用curl或者wget來代替。這種方式你能夠刪除再也不須要的文件,如解壓縮後的tar包,從而不須要再添加額外的layer到鏡像中。好比,你應該避免這樣使用:

ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all

  而應該如此:

RUN mkdir -p /usr/src/things \
    && curl -SL http://example.com/big.tar.xz \
    | tar -xJC /usr/src/things \
    && make -C /usr/src/things all

  對於不須要使用ADD命令tar包自動解壓縮功能的文件和目錄,你應該老是使用COPY。

ENTRYPOINT

Dockerfile reference for the ENTRYPOINT instruction
  使用ENTRYPOINT來設置鏡像的主命令,就像這個鏡像運行時就是這條命令同樣(而後再使用CMD做爲默認的flag)。
  咱們使用s3cmd命令做爲鏡像的主命令。

ENTRYPOINT ["s3cmd"]
CMD ["--help"]

VOLUME

Dockerfile reference for the VOLUME instruction
  VOLUME指令通常用於數據庫的存儲區域,配置存儲,或者docker容器建立的文件和目錄。

USER

Dockerfile reference for the USER instruction
  若是服務能夠在不須要特權的狀況下運行,那麼就應該使用USER來切換用戶至非root用戶。能夠用RUN命令建立用戶組和用戶如:

RUN groupadd -r postgres && useradd -r -g postgres postgres

  應該避免安裝和使用sudo,由於它有不可預知的TTY和信號轉移特性,會產生不少問題。若是的確必定要使用相似sudo的功能(如root下初始化daemon,非root下運行),可使用「gosu」。

WORKDIR

Dockerfile reference for the WORKDIR instruction
  爲了Dockerfile內容更加清晰和可靠,最好老是使用絕對路徑。一樣地,應該使用WORKDIR,而不是使用相似「cd … && do-something」這樣的指令,由於那樣會致使難以閱讀、查找錯誤和維護。

ONBUILD

Dockerfile reference for the ONBUILD instruction

其餘資源

Dockerfile Best Practices
Dockerfile Reference
https://github.com/docker-library/buildpack-deps/blob/master/jessie/Dockerfile
.dockerignore file
http://dockone.io/article/2034
https://docs.resin.io/deployment/build-optimisation/
  
others

相關文章
相關標籤/搜索