Când construiești o aplicație în Go, Rust, Java sau Next.js, ai nevoie de unelte grele în timpul compilării: compilatoare (gcc, g++), SDK-uri complete, fișiere sursă și pachete npm `devDependencies`. Dacă toate acestea rămân în imaginea finală de producție, imaginea va avea 1.5–2 GB și va conține sute de pachete vulnerabile din punct de vedere al securității.
Multi-Stage Builds permite utilizarea mai multor instrucțiuni FROM într-un singur fișier Dockerfile. Prima etapă (etichetată cu AS builder) instalează toate compilatoarele și produce binarul compilat sau folderul optimizat de producție.
A doua etapă pornește de la o imagine minimă (cum ar fi `alpine`, `distroless` sau `scratch`) și copiază exclusiv binarul rezultat din etapa anterioară (`COPY –from=builder /app/bin /bin`). Dimensiunea imaginii scade spectaculos de la 1.5 GB la doar 15–30 MB, fiind imună la majoritatea atacurilor cibernetice.
Sintaxă, opțiuni și concepte cheie
| Opțiune / Concept | Descriere practică |
|---|---|
FROM |
Definește o etapă intermediară izolată cu un nume specific. |
COPY --from= |
Extrage exclusiv fișierele compilate din etapa anterioară în imaginea finală. |
Distroless / Scratch / Alpine |
Imagini de bază ultra-ușoare ce nu conțin shell sau utilitare inutile de sistem. |
Reduced Attack Surface |
Minimizarea suprafeței de atac prin eliminarea compilatoarelor și a pachetelor de debug din producție. |
Exemple practice și cod
Exemplul 1: Dockerfile multi-stage pentru o aplicație în Go (reducere de la 800 MB la 15 MB)
Model de aur de Dockerfile pentru producție.
# Etapa 1: Compilare (Builder)
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Compilăm un binar static fără dependențe dinamice C:
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/server .
# Etapa 2: Imaginea finală de producție (Runner)
FROM alpine:3.20
WORKDIR /app
RUN apk --no-cache add ca-certificates tzdata
# Copiem exclusiv binarul executabil din prima etapă:
COPY --from=builder /app/server /app/server
USER 10001
EXPOSE 8080
CMD ["/app/server"]
Rezultat & Impact
Imagine finală de doar 16 MB cu pornire instantanee și securitate maximă.
Greșeli frecvente și bune practici
- Copierea fișierelor de cod înainte de `go mod download` sau `npm install`, ceea ce anulează mecanismul de cache pe layere la orice mică modificare de cod.
- Lăsarea utilizatorului implicit `root` în imaginea finală de producție în loc de definirea unui utilizator non-privilegiat.