Tips on Dockerfile
Dockerfile 看似簡單,幾行 FROM、RUN、COPY 就能把應用打包成 image,但寫得好不好,直接牽動 build 速度、image 大小、安全性與日後的可維護性。本文整理幾個實務中最常用、卻也最常被忽略的 Dockerfile 撰寫訣竅。 (一)善用 layer cache , 指令由 變動較少 排到 容易變化 (由上到下) Docker build 是逐層(layer)快取的,只要某一層的指令或內容改變,該層之後的所有 layer 都會失效重建。因此在Dockerfile內容中,指令順序(由上到下)應該從「變動頻率低」排到「變動頻率高」。最典型的例子,是先複製相依清單、安裝套件,最後才複製原始碼: # 先處理相依,讓 cache 命中率最大化 COPY package.json package-lock.json ./ RUN npm ci COPY . . 如此一來,只要原始碼變動、相依沒變, npm ci 這一層就能命中 cache,不必重跑。 (二)用 multi-stage build 縮小 image 把「編譯環境」與「執行環境」分開,只把最終產物帶進 runtime image,可大幅縮小體積,也降低受攻擊面(attack surface): FROM golang:1.22 AS builder WORKDIR /app COPY . . RUN go build -o server . FROM alpine:3.20 COPY --from=builder /app/server /server ENTRYPOINT ["/server"] runtime image 不再包含 compiler 與原始碼,從數百 MB 降到數十 MB 是常態。 (三)合併 RUN 並在同一層清理 cache 每一個 RUN 都是一層。把相關指令用 && 串接成一層,並在同一層清掉套件快取,避免多餘體積殘留在 image 裡: RUN apk add --no-cache curl \ && rm -rf /var/cache/apk/* Debian/Ubuntu 則常見 apt-get install 之後接 rm -rf /var/l...