準則
指令注意事項
FROM
Dockerfile reference for the FROM instruction
任何時候,盡量使用官方鏡像源作為你鏡像的基礎鏡像。我們建議使用Debian Image,因為其被很好地管理著,并且作為一個完整的發布包,但體積卻保持著最小化(當前不足150MB)。
1. FROM必須是除了注釋以外的第一行;
2. 可以有多個FROM語句,來創建多個image;
LABEL
Dockerfile reference for the LABEL instruction
RUN
Dockerfile reference for the RUN instruction
RUN語句有兩種格式:
1. RUN (the command is run in a shell - /bin/sh -c - shell form)
2. RUN ["executable", "param1", "param2"] (exec form)
apt-get
盡量避免使用RUN apt-get upgrade或者dist-upgrade,因為基礎鏡像的很多核心包不會再未授權的容器中升級。
要結合RUN apt-get update和apt-get install在同一個RUN語句下一起使用。如:
RUN apt-get update && apt-get install -y / package-bar / package-baz / package-foo
如果將update和install分開使用,執行多個Dockerfile時,會引起緩存問題,導致后面執行的install語句會失敗。
另外,執行完apt-get語句后,最后最好加上刪除安裝包的語句,以減小鏡像的體積。如:
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”,所以不需要明確地刪除指令。
管道使用
很多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選項。如:
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.3ENV PG_VERSION 9.3.4RUN 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.txtCOPY . /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/thingsRUN 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用戶??梢杂肦UN命令創建用戶組和用戶如:
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
新聞熱點
疑難解答
圖片精選