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-sharesCPU 共享(相對權重)
--cpuset-cpus允許執行的 CPU (0-3, 0,1)
--cpuset-mems允許執行的記憶體 (0-3, 0,1)
--disable-content-trusttrue略過映像檔驗證
-f, --fileDockerfile 的名稱(預設為 PATH/Dockerfile
--force-rm一律移除中間容器
--iidfile將映像檔 ID 寫入檔案
--isolation容器隔離技術
--label設定映像檔的詮釋資料
-m, --memory記憶體限制
--memory-swap交換限制等於記憶體加上交換:-1 表示啟用無限交換
--networkAPI 1.25+ 設定建構期間 RUN 指令的網路模式
--no-cache建構映像檔時不使用快取
--platformAPI 1.38+ 如果伺服器支援多平台,則設定平台
--pull一律嘗試提取較新版本的映像檔
-q, --quiet隱藏建構輸出,並在成功時印出映像檔 ID
--rmtrue建構成功後移除中間容器
--security-opt安全性選項
--shm-size/dev/shm 的大小
--squashAPI 1.25+ 實驗性 (守護行程) 將新建構的圖層壓縮成單個新圖層
-t, --tag名稱,以及選擇性的標籤,格式為 name:tag
--target設定要建構的目標建構階段。
--ulimitUlimit 選項

範例

指定容器的隔離技術 (--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.txtregistry://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