Docker 鏡像體積直接影響部署速度、儲存成本與安全攻擊面。本文透過「基礎鏡像替換、多階段建構、層數優化、快取清理」四大策略,示範如何將一個 Ubuntu+Nginx+2048 遊戲的示範專案從傳統寫法的 ~500MB 壓縮至 10MB 以下。

# 傳統 Dockerfile(~500MB+)
FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y nginx zip curl
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN curl -o /usr/share/nginx/www/master.zip -L https://codeload.github.com/gabrielecirulli/2048/zip/master
RUN cd /usr/share/nginx/www/ && unzip master.zip && mv 2048-master/* . && rm -rf 2048-master master.zip
EXPOSE 80
CMD ["/usr/sbin/nginx", "-c", "/etc/nginx/nginx.conf"]
ubuntu:12.04 基礎層即 100MB+RUN 產生一層,中間產物(apt cache、下載的 zip、解壓暫存檔)永久保留/var/lib/apt/lists/*# 階段 1:建構階段(含建構工具)
FROM alpine:latest AS builder
RUN apk add --no-cache nginx unzip curl
RUN mkdir -p /usr/share/nginx/html && \
curl -sSL https://codeload.github.com/gabrielecirulli/2048/zip/master -o /tmp/2048.zip && \
unzip -q /tmp/2048.zip -d /tmp && \
mv /tmp/2048-master/* /usr/share/nginx/html/ && \
rm -rf /tmp/2048.zip /tmp/2048-master
# 階段 2:運行階段(極精簡)
FROM alpine:latest
COPY --from=builder /usr/share/nginx/html /usr/share/nginx/html
COPY --from=builder /etc/nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
apk 極快,--no-cache 避免快取殘留# 語法:FROM AS → COPY --from=
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp .
FROM alpine:3.18
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
FROM,每階段獨立快取| 反模式 | 最佳實踐 | |||
|---|---|---|---|---|
| 多個獨立 RUN | 單一 RUN 串聯 &&,末尾清理快取 | |||
| RUN apt-get update && apt-get install -y pkg | RUN apt-get update && apt-get install -y pkg && rm -rf /var/lib/apt/lists/* | |||
| COPY 後再 RUN 修改權限 | COPY --chown=user:group 或建構階段預設權限 |
| 版本 | 基礎鏡像 | 鏡像大小 | 建構時間 | 關鍵優化 |
|---|---|---|---|---|
| 傳統 | ubuntu:12.04 | ~520 MB | ~3 min | 無 |
| Alpine 單階段 | alpine:latest | ~45 MB | ~1 min | 基礎鏡像替換 |
| Alpine 多階段 | alpine:latest | ~12 MB | ~1.5 min | 建構/運行分離 |
| Distroless 多階段 | gcr.io/distroless/static | ~8 MB | ~1.5 min | 無 Shell、最小攻擊面 |
| Scratch 靜態編譯 | scratch | ~3 MB | ~2 min | 僅二進位檔 |
遵循「最小基礎鏡像 + 多階段建構 + 單層合併 + 徹底清理」原則,配合 dive 定期審視層級結構,可將生產鏡像控制在極小體積,加速 CI/CD 流水線與生產部署。