Cách tối ưu nhất là dùng multi-stage build: stage đầu tiên sử dụng image golang:1.22-alpine để compile source thành binary, stage thứ hai chỉ dùng scratch (image rỗng hoàn toàn) hoặc gcr.io/distroless/static rồi copy binary vào, cho ra final image chỉ 5-15MB thay vì hơn 1GB của golang base image.
- Để binary chạy được trên scratch image, cần set
CGO_ENABLED=0khi build để tạo static binary không phụ thuộc vào thư viện C bên ngoài. - Nên tách layer
COPY go.mod go.sumvàRUN go mod downloadriêng trước khi copy source code, để Docker cache lại dependency layer và chỉ rebuild khi dependency thay đổi, giúp tăng tốc build đáng kể.
Use multi-stage builds: the first stage uses golang:1.22-alpine to compile the binary; the second stage uses scratch (empty image) or gcr.io/distroless/static and only copies the binary in — yielding a final image of 5-15MB versus 1GB+ for the full golang base image.
- Set
CGO_ENABLED=0at build time to produce a fully static binary that runs on scratch without external C libraries. - Split
COPY go.mod go.sumandRUN go mod downloadinto their own layer before copying source code so Docker caches the dependency layer and only rebuilds it when dependencies change, significantly speeding up builds.