Dockerfile注意事項

2022-08-16 02:09:21 字數 4413 閱讀 1876

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

避免安裝不必須的包。

每個容器應該只關注乙個功能點。

最小化映象的層數。

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

對構建快取要有清楚的認識。

dockerfile reference for the from instruction

任何時候,盡量使用官方映象源作為你映象的基礎映象。我們建議使用debian image,因為其被很好地管理著,並且作為乙個完整的發布包,但體積卻保持著最小化(當前不足150mb)。

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

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

3.dockerfile reference for the label instruction

dockerfile reference for the run instruction

run語句有兩種格式:

1. run

盡量避免使用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 -  | wc -l > /number
docker使用/bin/sh -c直譯器來執行這些命令,該直譯器只評估管道最後乙個操作的返回值來判斷整個命令是否成功。在上面的例子中,只要wc -l命令成功了,即使wget命令失敗了,也會建立乙個新映象。為了避免上述情況,可以在語句首部加上set -o pipefail &&。比如:

run set -o pipefail && wget -o -  | wc -l > /number
注意:並非所有的shell都支援-o pipefail選項,比如說基於debian的映象下的模式shell:dash shell。這種情況下,我們可以使用exec格式的run命令來顯示地選擇shell來支援pipefail選項。如:

run ["/bin/bash", "-c", "set -o pipefail && wget -o -  | wc -l > /number"]
dockerfile reference for the cmd instruction

cmd語句與run不同,run是在build映象的時候執行,而cmd語句是在build結束後執行。乙個dockerfile鐘可以有多個run語句,雖然也可以有多個cmd語句,但是卻只有最後一條cmd語句會執行。cmd語句格式為:

cmd [「executable」, 「param1」, 「param2」…]
dockerfile reference for the expose instruction

expose指令指明容器會監聽鏈結的埠。因此,最好使用常用的、傳統的應用埠。比如,apache web伺服器使用expose 80等。

為了給外部鏈結使用,你需要使用docker run命令來制定容器埠和host埠的對映。

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 | tar -xjc /usr/src/postgress && …

env path /usr/local/postgres-$pg_major/bin:$path

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  /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 \

| tar -xjc /usr/src/things \

&& make -c /usr/src/things all

對於不需要使用add命令tar包自動解壓縮功能的檔案和目錄,你應該總是使用copy。

dockerfile reference for the entrypoint instruction

使用entrypoint來設定映象的主命令,就像這個映象執行時就是這條命令一樣(然後再使用cmd作為預設的flag)。

我們使用s3cmd命令作為映象的主命令。

entrypoint ["s3cmd"]

cmd ["--help"]

dockerfile reference for the volume instruction

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

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」。

dockerfile reference for the workdir instruction

為了dockerfile內容更加清晰和可靠,最好總是使用絕對路徑。同樣地,應該使用workdir,而不是使用類似「cd … && do-something」這樣的指令,因為那樣會導致難以閱讀、查詢錯誤和維護。

dockerfile reference for the onbuild instruction

dockerfile best practices

dockerfile reference

.dockerignore file

others

DOCKERFILE注意事項

盡量將dockerfile放在空目錄中,如果目錄中必須有其他檔案,則使用.dockerignore檔案。避免安裝不必須的包。每個容器應該只關注乙個功能點。最小化映象的層數。多行引數時應該分類。這樣更清晰直白,便於閱讀和review,另外,在每個換行符 前都增加乙個空格。對構建快取要有清楚的認識。do...

dockerFile常用命令及注意事項

from scratch 製作基礎base image from centos 製作基礎base image 備註 盡量使用官方的image作為base image label maintainer test label version 1.0 label description this is d...

java DOM 注意事項

1.w3c把標籤內的文字部分也定義成乙個node 2.element物件代表的是xml文件中的標籤元素 繼承於node,亦是node的最主要的子物件 3.attr實際上是包含在element中的,它並不能被看作是element的子物件,因而在dom中attr並不是dom樹的一部分,所以node中的 ...