docker build(舊版建構器)
說明 | 從 Dockerfile 建置映像檔 |
---|---|
用法 | docker image build [選項] 路徑 | URL | - |
別名 | docker image build docker build docker builder build |
說明
重要
此頁面指的是使用舊版(BuildKit 之前的)建置後端的
docker build
**舊版實作**。此設定僅與您建置 Windows 容器時相關。有關使用 Buildx 的預設
docker build
資訊,請參閱docker buildx build
。
使用舊版建置器建置時,映像檔是透過執行一系列的 提交 從 Dockerfile 建立的。與使用 BuildKit 相比,此過程效率低下且速度緩慢,這就是為什麼除了建置 Windows 容器之外,所有用例都不建議使用此建置策略。它仍然適用於建置 Windows 容器,因為 BuildKit 尚未針對 Windows 提供完整的功能同等性。
使用 docker build
呼叫的建置預設使用 Buildx(和 BuildKit),除非
- 您正在 Windows 容器模式下執行 Docker Engine
- 您透過設定環境變數
DOCKER_BUILDKIT=0
明確選擇停用 BuildKit。
此頁面上的說明僅涵蓋舊版建置器專有的資訊,以及舊版建置器中的行為與 BuildKit 中的行為不同的情況。有關舊版建置器和 BuildKit 之間通用的功能和旗標(例如 --tag
和 --target
)的資訊,請參閱 docker buildx build
的文件。
使用舊版建置器的建置上下文
建置上下文是您在呼叫 build 指令時傳遞的位置參數。在以下範例中,上下文是 .
,表示目前的工
$ docker build .
使用傳統建構器時,建構上下文會完整地發送到守護行程。使用 BuildKit 時,只會傳輸您在建構中使用的檔案。傳統建構器不會事先計算它需要的檔案。這表示對於具有大型上下文的建構,即使您只使用上下文中包含的檔案子集,上下文傳輸也可能需要很長時間。
因此,使用傳統建構器時,仔細考慮您在指定的上下文中包含哪些檔案格外重要。使用 .dockerignore
檔案來排除您在建構中不需要的檔案和目錄,使其不被作為建構上下文的一部分發送。
存取建構上下文之外的路徑
如果您嘗試在 Dockerfile 中使用相對路徑存取建構上下文之外的檔案,傳統建構器會出錯。
FROM alpine
COPY ../../some-dir .
$ docker build .
...
Step 2/2 : COPY ../../some-dir .
COPY failed: forbidden path outside the build context: ../../some-dir ()
另一方面,BuildKit 會去除遍歷到建構上下文之外的前導相對路徑。重複使用前面的範例,路徑 COPY ../../some-dir .
在 BuildKit 中會被評估為 COPY some-dir .
。
選項
選項 | 預設值 | 說明 |
---|---|---|
--add-host | 新增自訂主機到 IP 的映射 (host:ip ) | |
--build-arg | 設定建構時期變數 | |
--cache-from | 視為快取來源的映像檔 | |
--cgroup-parent | 設定建構期間 RUN 指令的父 cgroup | |
--compress | 使用 gzip 壓縮建構上下文 | |
--cpu-period | 限制 CPU CFS(完全公平排程器)週期 | |
--cpu-quota | 限制 CPU CFS(完全公平排程器)配額 | |
-c, --cpu-shares | CPU 共享(相對權重) | |
--cpuset-cpus | 允許執行的 CPU (0-3, 0,1) | |
--cpuset-mems | 允許執行的記憶體 (0-3, 0,1) | |
--disable-content-trust | true | 略過映像檔驗證 |
-f, --file | Dockerfile 的名稱(預設為 PATH/Dockerfile ) | |
--force-rm | 一律移除中間容器 | |
--iidfile | 將映像檔 ID 寫入檔案 | |
--isolation | 容器隔離技術 | |
--label | 設定映像檔的詮釋資料 | |
-m, --memory | 記憶體限制 | |
--memory-swap | 交換限制等於記憶體加上交換:-1 表示啟用無限交換 | |
--network | API 1.25+ 設定建構期間 RUN 指令的網路模式 | |
--no-cache | 建構映像檔時不使用快取 | |
--platform | API 1.38+ 如果伺服器支援多平台,則設定平台 | |
--pull | 一律嘗試提取較新版本的映像檔 | |
-q, --quiet | 隱藏建構輸出,並在成功時印出映像檔 ID | |
--rm | true | 建構成功後移除中間容器 |
--security-opt | 安全性選項 | |
--shm-size | /dev/shm 的大小 | |
--squash | API 1.25+ 實驗性 (守護行程) 將新建構的圖層壓縮成單個新圖層 | |
-t, --tag | 名稱,以及選擇性的標籤,格式為 name:tag | |
--target | 設定要建構的目標建構階段。 | |
--ulimit | Ulimit 選項 |
範例
指定容器的隔離技術 (--isolation)
當您在 Windows 上執行 Docker 容器時,此選項很有用。--isolation=<value>
選項設定容器的隔離技術。在 Linux 上,唯一支援的選項是使用 Linux 命名空間的 default
選項。在 Microsoft Windows 上,您可以指定下列值
值 | 說明 |
---|---|
default | 使用 Docker 守護行程的 --exec-opt 指定的值。如果守護行程未指定隔離技術,Microsoft Windows 會使用 process 作為其預設值。 |
process | 僅命名空間隔離。 |
hyperv | 基於 Hyper-V 虛擬機器管理程式的分割區隔離。 |
指定沒有值的 --isolation
旗標與設定 --isolation="default"
相同。
選用安全性選項 (--security-opt)
此旗標僅在 Windows 上執行的守護行程上受支援,且僅支援 credentialspec
選項。 credentialspec
必須採用 file://spec.txt
或 registry://keyname
的格式。
壓縮映像檔的圖層 (--squash) (實驗性)
概觀
注意
--squash
選項是一項實驗性功能,不應視為穩定功能。
建構映像檔後,此旗標會將新的圖層壓縮成具有單個新圖層的新映像檔。壓縮不會破壞任何現有映像檔,而是會建立一個包含壓縮圖層內容的新映像檔。這實際上使其看起來像是所有 Dockerfile
指令都是使用單個圖層建立的。--squash
旗標會保留建構快取。
如果您的 Dockerfile 產生多個修改相同檔案的圖層,壓縮圖層可能會有好處。例如,在一個步驟中建立的檔案,然後在另一個步驟中移除。對於其他使用案例,壓縮映像檔實際上可能會對效能產生負面影響。提取由多個圖層組成的映像檔時,守護行程可以並行提取圖層,並允許在映像檔之間共享圖層(節省空間)。
對於大多數使用案例,多階段建構是更好的替代方案,因為它們可以更精細地控制您的建構,並且可以利用建構器未來的優化。請參閱多階段建構章節以了解更多資訊。
已知限制
--squash
選項有一些已知的限制
- 壓縮圖層時,產生的映像檔無法利用與其他映像檔的圖層共享,並且可能會使用更多空間。仍然支援共享基礎映像檔。
- 使用此選項時,您可能會看到使用的空間明顯增加,因為儲存了映像檔的兩個副本,一個用於具有所有完整快取圖層的建構快取,另一個用於壓縮版本。
- 雖然壓縮圖層可能會產生較小的映像檔,但它可能會對效能產生負面影響,因為單個圖層需要更長的時間來解壓縮,而且您無法並行下載單個圖層。
- 當嘗試壓縮一個沒有對檔案系統進行更改的映像檔時(例如,Dockerfile 只包含
ENV
指令),壓縮步驟將會失敗(參見 問題 #33823)。
先決條件
此頁面上的範例使用 Docker 23.03 的實驗模式。
您可以透過在啟動 Docker daemon 時使用 --experimental
旗標,或在 daemon.json
設定檔中設定 experimental: true
來啟用實驗模式。
預設情況下,實驗模式是停用的。要查看 Docker daemon 的目前設定,請使用 docker version
命令並檢查 Engine
區段中的 Experimental
行。
Client: Docker Engine - Community
Version: 23.0.3
API version: 1.42
Go version: go1.19.7
Git commit: 3e7cbfd
Built: Tue Apr 4 22:05:41 2023
OS/Arch: darwin/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.3
API version: 1.42 (minimum version 1.12)
Go version: go1.19.7
Git commit: 59118bf
Built: Tue Apr 4 22:05:41 2023
OS/Arch: linux/amd64
Experimental: true
[...]
使用 --squash
旗標建置映像檔
以下是用 --squash
旗標建置的範例。以下是 Dockerfile
FROM busybox
RUN echo hello > /hello
RUN echo world >> /hello
RUN touch remove_me /remove_me
ENV HELLO=world
RUN rm /remove_me
接下來,使用 --squash
旗標建置一個名為 test
的映像檔。
$ docker build --squash -t test .
建置完成後,歷史記錄如下所示。歷史記錄可能會顯示圖層的名稱為 <missing>
,並且有一個新的圖層的註釋為 merge
。
$ docker history test
IMAGE CREATED CREATED BY SIZE COMMENT
4e10cb5b4cac 3 seconds ago 12 B merge sha256:88a7b0112a41826885df0e7072698006ee8f621c6ab99fca7fe9151d7b599702 to sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
<missing> 5 minutes ago /bin/sh -c rm /remove_me 0 B
<missing> 5 minutes ago /bin/sh -c #(nop) ENV HELLO=world 0 B
<missing> 5 minutes ago /bin/sh -c touch remove_me /remove_me 0 B
<missing> 5 minutes ago /bin/sh -c echo world >> /hello 0 B
<missing> 6 minutes ago /bin/sh -c echo hello > /hello 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff 1.113 MB
測試映像檔,檢查 /remove_me
是否已消失,確認 hello\nworld
是否在 /hello
中,確認 HELLO
環境變數的值是否為 world
。