Docker Image Boyutunu Küçültmek: Multi-stage Build ve Distroless Teknikleri
Büyük container imajları hem depolama hem ağ çekimi hem de yüzey alanı (CVE) açısından pahalıdır. Docker image boyutunu düşürmek için en etkili kalıplardan biri multi-stage build; ikinci sık tercih ise çalışma imajı olarak distroless veya minimal taban kullanmaktır.
Multi-stage build nedir?
İlk aşamada derleme araçları (Go toolchain, npm install, gcc…) bulunur; son aşamaya yalnızca çalıştırma için gerekli dosyalar kopyalanır. Böylece final imajda git, build-essential veya node_modules dev bağımlılıkları kalmaz.
Go örneği
# build stage
FROM golang:1.22-bookworm AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server ./cmd/server
# run stage — küçük taban
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /app/server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]
CGO_ENABLED=0 statik binary üretmeye yardımcı olur; distroless’ta dinamik linker aramak zorunda kalmazsınız (projeye göre değişir).
Node.js örneği (özet)
FROM node:20-bookworm AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
FROM node:20-bookworm AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM gcr.io/distroless/nodejs20-debian12
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
# ...
Distroless Node imajlarında shell yok; docker exec ile debug zorlaşır — üretim için iyidir, geliştirme için ayrı Dockerfile hedefi kullanın.
Distroless ve Alpine
| Taban | Boyut | Not |
|---|---|---|
distroless |
Çok küçük | Paket yöneticisi yok, saldırı yüzeyi az |
alpine |
Küçük | musl uyumluluğu; bazı native modüller sorun çıkarabilir |
debian-slim |
Orta | Uyumluluk / kolay debug dengesi |
Alpine cazip görünür; ancak glibc bekleyen binary’lerde sürprizler yaşanabilir. Go için statik build + distroless sık kombinasyon.
Katman önbelleği
COPY go.mod go.sum ve RUN go mod download önce gelirse bağımlılık katmanı nadiren invalid olur. package.json + npm ci için aynı mantık.
Güvenlik
Küçük imaj = daha az paket = daha az CVE. Yine de taban imajını düzenli yeniden build edin; docker scout veya registry taramalarını CI’a alın.
Özet
- Multi-stage build, derleme araçlarını final imajdan çıkarır.
- Distroless veya minimal taban + statik binary, Docker image boyutunu ve saldırı yüzeyini düşürür.
- Alpine ile dikkatli olun; üretimde statik Go binary +
distroless/staticsık görülen bir kalıptır.
CI/CD ve üretim ortamı için PgBouncer ile veritabanı katmanını da aynı “ince ve öngörülebilir” çizgide tutmak performansı tamamlar.
İlgili Yazılar
StatefulSet ve Deployment Arasindaki Farklar: Kritik Noktalar
Kubernetes'te StatefulSet ve Deployment kaynaklarinin farklarini, hangi workload icin hangisinin dogru oldugunu, operasyonel riskleri ve production'da dikkat edilmesi gereken kritik noktalarni detayli inceliyoruz.
gRPC vs REST: Ne Zaman Hangisini Kullanmalısın? Go ile Karşılaştırmalı Rehber
Mikroservislerde gRPC ve REST farkları; protobuf, HTTP/2, tarayıcı uyumu ve Go örnekleri. REST ile Go servis karşılaştırması için iç link.
PostgreSQL Connection Pooling: PgBouncer Kurulumu ve Go/Node.js ile Kullanımı
Üretimde bağlantı tüketimini yönetmek: PgBouncer transaction pooling, Go database/sql ve Node.js pg havuz ayarları.