前言
先說在前面——你是不是常常隨意地寫 Dockerfile 呢?其實只要稍微用點心思,就能讓映像檔更輕量、可讀性更高。 這次就來介紹幾個實用的小技巧。
一:善用多階段建置(Multi-Stage Build)
Docker 的多階段建置功能,是指在建置過程中將「編譯階段」與「執行階段」分開, 這樣最終的映像檔就能變得更精簡。以下以建立 Go 語言容器為例,來看看這樣做有什麼好處。
錯誤範例FROM golang:1.25
WORKDIR /app
COPY . .
RUN go build -o myapp .
CMD ["./myapp"]
正確範例
# Stage 1: Build
FROM golang:1.25 AS builder
WORKDIR /app
RUN --mount=type=bind,source=.,target=/src,readonly \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
cd /src && go build -o /app/myapp .
# Stage 2: Run
FROM alpine:3.22.1
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]
接著,我們實際來 build 上面這兩個 Dockerfile,看看最終映像檔的容量差異有多大。這裡先用一個簡單的架構:由 main.go 與 go.mod 所組成的 Go 應用程式作為例子。實際 build 之後比較結果,竟然相差 80 倍!這次雖然只是用一個很小的範例來測試,但差距已經這麼大了。 若在實際專案中完整使用,差距恐怕會更驚人。
test@mymac senior % docker image ls | grep myapp
myapp-senior latest 953f175978a5 13 seconds ago 16.9MB
myapp-junior latest 8a57b08592c6 32 seconds ago 1.3GB
test@mymac senior %
二:一定要固定 Base Image 的版本
錯誤範例
FROM golang:latest
正確範例
FROM golang:1.25-alpine
如果忽略這點,今天能 build 的專案,明天可能就突然無法 build 了。今天這樣寫可以正常 build,但如果明天 latest 被更新了會怎樣呢? 你的 build 很可能突然就會失敗。
重點如下:
- 指定 LTS 的特定版本號(例如
1.23) - 若可能,使用輕量版映像(例如
alpine或bullseye-slim)
這樣不僅能避免預期外的問題,也能減少映像大小。實際上可縮小約 4 倍
三:盡量減少 Layer 數量
下一個重點是「盡可能減少層數(Layer)」。這麼做有以下好處:
- 減少映像檔大小(不殘留多餘檔案)
- 提升快取效率(縮短重建時間)
- 加快部署速度(層數越少,push/pull 越快)
四:善用 .dockerignore
.dockerignore 的用途和 .gitignore 類似,可以指定哪些檔案不應該被打包進映像中。
五:建立具安全意識的 Dockerfile
Docker 安全性最佳實務可歸納為以下四點:
- 使用 可信且輕量的 Base Image
- 採用 多階段建置
- 定期重新建置 映像
- 檢查映像的漏洞
使用可信的 Base Image
Docker Hub 上有非常多映像,但應優先選擇:
- Official Image(官方映像)
- Verified Publisher(官方驗證發佈者)
這些映像在名稱旁會有官方標誌。此外,盡量選擇小型映像(如 alpine、slim),可降低攻擊面與漏洞風險。
採用多階段建置
如前所述,利用多階段建置可確保最終映像中不含不必要的工具與檔案,進而避免潛在漏洞並減少攻擊面。
定期重新建置映像
若長期使用多年未更新的映像,即使原軟體後來修補了漏洞,你的映像仍會保留舊漏洞。建議定期重新建置。
結論
以下是本文介紹的五個重點: 活用多階段建置 → 讓映像更輕量、移除不必要依賴 固定 Base Image 版本 → 提高重現性、避免意外失敗 減少 Layer 數量 → 提升快取效率與建置速度 善用 .dockerignore → 避免打包無關檔案 強化安全性意識 → 使用可信映像、定期更新與掃描漏洞
只要在日常開發中多留意這些細節, 你的映像就能更 輕量、快速、安全。 下次撰寫 Dockerfile 時,不妨嘗試實踐其中的一項看看吧。











