—— 多階段建置(Multi-stage Build)完整解析
📘 一、什麼是 FROM xxx AS builder
在 Dockerfile 中,FROM ubuntu:24.04 AS builder 表示「建立一個名為 builder 的建置階段」。
這個階段通常用來編譯或打包應用程式,後續可以在另一個階段中用:
COPY --from=builder /path/in/build /path/in/final
把編譯好的成果(例如可執行檔或壓縮包)複製到乾淨、輕量的最終映像中。
最終映像只會包含執行應用程式所需的檔案,不會帶入完整的建置工具與相依套件。
⚙️ 二、運作原理
- 每一個
FROM都代表一個新的階段(相當於一個暫時的映像層)。 AS builder給這個階段命名,方便後續引用。- 最後只有「最後一個階段」的內容會保留成最終映像,其餘階段不會被包含在成品中。
💡 三、優點
- 映像更小:只保留執行所需檔案,捨去編譯工具與 headers。
- 更安全:沒有
gcc、make等工具,降低攻擊面。 - 清晰分離責任:編譯與執行分開,易於維護。
- 快取效率更好:編譯階段可以重複使用快取,不影響最終映像。
- 靈活性高:可以產生多個產物或目標映像。
🧰 四、常見應用場景
- 從原始碼編譯:例如自行編譯 Postfix、Nginx、Redis。
- 前後端分離建置:前端用 Node 編譯,最後部署到 nginx/alpine。
- 多階段產出:同一份 Dockerfile 生成多種不同的成品。
- 產物打包:先在 builder 階段壓縮或打包,再放入乾淨的環境。
🧱 五、實際範例:編譯 Postfix
# === 第一階段:編譯階段 ===
FROM ubuntu:24.04 AS builder
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ARG DEBIAN_FRONTEND=noninteractive
ARG POSTFIX_VERSION=3.10.4
ARG POSTFIX_SRC_URL="https://archive.postfix.org/official/postfix-${POSTFIX_VERSION}.tar.gz"
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl build-essential pkg-config \
libssl-dev libsasl2-dev \
libmariadb-dev-compat libmariadb-dev \
liblmdb-dev zlib1g-dev m4 \
libpcre2-dev && rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src
RUN curl -L "$POSTFIX_SRC_URL" -o postfix.tgz \
&& tar xzf postfix.tgz && cd postfix-* \
&& make -f Makefile.init makefiles CCARGS='-DUSE_TLS -DUSE_SASL_AUTH -DUSE_LMDB -DUSE_PCRE2 -DUSE_MYSQL' \
AUXLIBS='-lssl -lcrypto -lsasl2 -llmdb -lpcre2-8 -lz -lmariadb' \
&& make && mkdir -p /out && cp -r ./out/* /out/
# === 第二階段:執行階段 ===
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates libsasl2-2 \
liblmdb0 zlib1g \
libpcre2-8-0 libmariadb3 \
libssl3 && rm -rf /var/lib/apt/lists/*
COPY --from=builder /out/ /
EXPOSE 25 587
CMD ["/usr/sbin/postfix", "start-fg"]
結果:
- 第一階段(builder)有編譯工具;
- 第二階段只保留 Postfix 執行檔,映像乾淨、安全又輕量。
🔍 六、實務建議
- 保持 builder 與 runtime 使用相同基底版本(避免動態庫不相容)。
- 用
ldd檢查可執行檔依賴哪些動態庫,縮減最終映像。 - 用
--target測試單一階段(方便 CI 驗證)。 - 使用非 root 帳號與最小權限啟動應用。
- 若需使用機密(SSH key、token),搭配 BuildKit 的 secret mount 機制。
✅ 結論
FROM ... AS builder 是 Docker 多階段建置的核心技巧。
它讓我們在「肥」的建置階段做完編譯,再把成果抽出放入「瘦」的最終映像,
兼顧 體積小、安全高、可重現、可維護 —— 是現代 Dockerfile 的最佳實踐。