Docker Multi-Stage Build Rehberi: Image Boyutunu %80 Küçültün (2026)

24.04.2026 13:25 Haber

Docker image'larınız gigabyte'larca mı yer kaplıyor? Production ortamında dev tools, test dosyaları, kaynak kodlar gereksiz yere bulunuyor mu? Alesta Web olarak yüzlerce DevOps projesinde karşılaştığımız bu probleme kesin çözüm: Docker multi-stage build. Bu rehberde, image boyutunu %80 küçülten bu tekniği (reduce Docker image size by 80%) adım adım öğreneceksiniz — Node.js, Go ve Python örnekleriyle.

Docker Multi-Stage Build Nedir? (What is Docker Multi-Stage Build?)

Docker multi-stage build, tek bir Dockerfile içinde birden fazla FROM komutu kullanarak farklı "stage" (aşama) tanımlamanıza olanak tanıyan bir tekniktir. Alesta Web ekibi olarak bunu şöyle açıklıyoruz: bir "inşaat aşaması" ve bir "çalışma aşaması" düşünün. İnşaat aşamasında tüm derleme araçlarını kullanırsınız; çalışma aşamasında yalnızca gereken binary dosyayı kopyalarsınız.

Docker 17.05 sürümüyle 2017'de hayatımıza giren bu özellik (introduced in Docker 17.05), özellikle compiled dillerde (Go, Java, Rust) devrimsel bir etki yarattı. Ama Node.js, Python gibi yorumlanan dillerde de son derece etkili. Yani hangi stack'i kullanırsanız kullanın, docker multi-stage build işinize yarayacak.

? Bilgi / Info:

Docker multi-stage build öncesinde geliştiriciler ayrı "builder" image'ları oluşturup shell script'lerle birleştirirdi. Bu hem karmaşık hem de bakımı zordu (maintainability issues). Multi-stage build bu süreci tek Dockerfile'a indirdi.

Neden Docker Multi-Stage Build Kullanmalısınız? (Why Use Multi-Stage Builds?)

Somut bir örnek verelim. Standart bir Node.js uygulaması için node:18 base image kullandığınızda boyut yaklaşık 1 GB'a çıkabiliyor. Aynı uygulamayı docker multi-stage build ile node:18-alpine final stage kullanarak oluşturduğunuzda boyut 150-200 MB'a iniyor. Go uygulamalarında bu fark daha da dramatik: 800 MB → 10 MB. Yani %98 küçülme (98% size reduction).

Ama boyut tek fayda değil. Alesta Web'in DevOps projelerinde gözlemlediğimiz somut avantajlar şunlar:

  • Güvenlik (Security): Production image'da derleyici, test araçları, kaynak kodu yok → saldırı yüzeyi küçülüyor (reduced attack surface)
  • Hız (Speed): Küçük image = hızlı pull, hızlı deployment → CI/CD pipeline süresi düşüyor
  • Maliyet (Cost): Docker registry bandwith, Kubernetes pod startup time, cloud storage maliyetleri azalıyor
  • Temizlik (Cleanliness): Tek Dockerfile, ayrı script yok, bakımı kolay
  • Cache optimizasyonu: Her stage ayrı cache layer'a sahip — build hızı artıyor
Teknoloji Normal Image Multi-Stage Image Küçülme / Reduction
Node.js ~1 GB ~150 MB ~85%
Go ~800 MB ~10 MB ~98%
Python ~1.2 GB ~200 MB ~83%
Java (Spring Boot) ~700 MB ~120 MB ~83%

Temel Sözdizimi (Basic Docker Multi-Stage Build Syntax)

Docker multi-stage build için Dockerfile yapısını öğrenmek sanıldığı kadar zor değil. Temel kural şu: her FROM komutu yeni bir stage başlatır. Stage'lere isim verebilirsiniz (AS builder gibi) ve son stage production image'ı oluşturur.

Temel Yapı / Basic Structure

# Stage 1: Builder (inşaat aşaması)
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Production (çalışma aşaması)
FROM node:18-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

Dikkat edin: COPY --from=builder komutu (copy from stage), önceki stage'den dosya kopyalamanın anahtarı. Bu sayede builder stage'indeki tüm araçlar, kaynak kodlar, test dosyaları production image'ına dahil olmuyor.

Stage'leri isimle veya sıra numarasıyla belirtebilirsiniz: COPY --from=0 (0. stage) ya da COPY --from=builder (isimle). Alesta Web ekibi olarak her zaman isim kullanmanızı öneririz — daha okunabilir ve bakımı kolay (more readable and maintainable).

Pratik Örnekler (Practical Multi-Stage Build Examples)

1. Node.js Multi-Stage Build (TypeScript + Alpine)

En yaygın kullanım senaryosu: TypeScript ile yazılmış Node.js uygulaması. Build aşamasında tsc ile derleme, production aşamasında sadece compiled JS çalıştırma.

Node.js + TypeScript Dockerfile

# Stage 1: Dependencies ve Build
FROM node:20-alpine AS builder
WORKDIR /app

# Önce package.json kopyala (cache optimizasyonu / cache optimization)
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

COPY tsconfig.json ./
COPY src ./src
RUN npx tsc --noEmit && npx tsc

# Stage 2: Production
FROM node:20-alpine AS production
ENV NODE_ENV=production
WORKDIR /app

# Sadece gerekli dosyalar / Only necessary files
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./

# Güvenlik için non-root user / Security: non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001
USER nextjs

EXPOSE 3000
CMD ["node", "dist/index.js"]
✅ Sonuç / Result:

Bu Dockerfile ile Node.js image boyutu 1 GB'dan 150 MB'a iniyor. Ayrıca non-root user kullanımı güvenlik açısından best practice (security best practice).

2. Go Multi-Stage Build (Statically Linked Binary)

Go, docker multi-stage build için adeta yaratılmış bir dil. Derleme sonrası ortaya çıkan statik binary, scratch veya distroless base image'ı ile çalışabiliyor — yani sıfıra yakın OS katmanı.

Go Dockerfile - Scratch Image (ultra-minimal)

# Stage 1: Build
FROM golang:1.22-alpine AS builder
WORKDIR /app

# Modülleri önce indir (cache optimization / önbellek optimizasyonu)
COPY go.mod go.sum ./
RUN go mod download

COPY . .

# CGO devre dışı = statically linked binary
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o server ./cmd/server

# Stage 2: Minimal production image
FROM scratch AS production
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

EXPOSE 8080
ENTRYPOINT ["/server"]

Go uygulamaları için scratch base image (empty image) kullandığınızda final image boyutu 5-15 MB oluyor. Bunu Alesta Web ekibi olarak mikroservis altyapılarında sıklıkla kullanıyoruz — Kubernetes pod startup süresi inanılmaz düşüyor (pod startup time drops significantly).

3. Python Multi-Stage Build (FastAPI / Django)

Python için multi-stage build biraz daha dikkat gerektiriyor çünkü Python yorumlanan bir dil — C extension'ları derlemek için build tools gerekebiliyor (build tools required for C extensions).

Python + FastAPI Dockerfile

# Stage 1: Builder (bağımlılıkları derle / compile dependencies)
FROM python:3.12-slim AS builder

# Build araçları yükle (install build tools)
RUN apt-get update && apt-get install -y \
    gcc \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt .

# Wheel dosyaları oluştur (create wheel files)
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt

# Stage 2: Production
FROM python:3.12-slim AS production

# Sadece runtime bağımlılıkları / Only runtime dependencies
RUN apt-get update && apt-get install -y \
    libpq5 \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=builder /app/wheels /wheels
RUN pip install --no-cache /wheels/*

COPY ./app ./app

EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Docker Multi-Stage Build: En İyi Pratikler (Best Practices)

Alesta Web ekibi olarak yüzlerce Dockerfile review'ından çıkardığımız en önemli best practices şunlar:

1. Cache Katmanlarını Akıllıca Kullanın

Docker, değişmeyen layer'ları cache'ler (caches unchanged layers). Bu nedenle sık değişen dosyaları (kaynak kod) sonraya, nadiren değişen dosyaları (package.json, go.mod) öne koyun.

Cache optimizasyonu / Cache optimization

# ❌ Kötü - kaynak kod her değiştiğinde npm install yeniden çalışır
COPY . .
RUN npm install

# ✅ İyi - package.json değişmediği sürece npm install cache'lenir
COPY package*.json ./
RUN npm install
COPY . .

2. .dockerignore Dosyası Kullanın

Multi-stage build ile birlikte .dockerignore dosyası da şart. node_modules, .git, test dosyaları, geçici dosyalar build context'e gönderilmemeli (should not be sent to build context).

.dockerignore örneği

node_modules
.git
.gitignore
*.md
dist
coverage
.env
.env.local
__pycache__
*.pyc
.pytest_cache

3. Spesifik Tag Kullanın

FROM node:latest yerine FROM node:20.11.1-alpine3.19 gibi spesifik versiyon kullanın. latest tag reproducible builds'ı (tekrarlanabilir build) bozar ve güvenlik sorunlarına yol açabilir (can cause security issues).

4. Minimal Base Image Seçin

Alpine, distroless, scratch — boyuta göre seçim yapın:

  • scratch: Sadece statically linked binary'ler için (Go, Rust)
  • distroless: Minimal OS katmanı, no shell (Google önerisi)
  • alpine: Küçük ama shell mevcut, debug kolaylığı
  • slim: Debian tabanlı, daha büyük ama uyumluluk iyi

Yaygın Hatalar ve Çözümleri (Common Errors and Solutions)

Hata 1: "COPY --from" ile Dosya Bulunamıyor

Hata Mesajı / Error Message

failed to solve: failed to compute cache key: failed to walk: lstat /app/dist: no such file or directory

Çözüm: Builder stage'de dosya oluştuğunu doğrulayın. Build komutu başarısız olmuş olabilir. RUN ls /app/dist ile kontrol edin.

Hata 2: Alpine'de Missing Libraries

Hata / Error

error while loading shared libraries: libstdc++.so.6: cannot open shared object file

Çözüm: Alpine'de musl libc kullanılır, glibc ile derlenmiş binary'ler çalışmaz. apk add libstdc++ gcompat ile eksik kütüphaneyi kurun veya debian-slim base image'ına geçin.

Hata 3: Docker BuildKit Etkin Değil

BuildKit aktif etme / Enable BuildKit

# Linux/Mac
export DOCKER_BUILDKIT=1
docker build -t myapp .

# Windows PowerShell
$env:DOCKER_BUILDKIT=1
docker build -t myapp .

# Ya da doğrudan / or directly
DOCKER_BUILDKIT=1 docker build -t myapp .

Docker 23.0+ sürümlerinde BuildKit zaten varsayılan olarak aktif (enabled by default). Daha eski sürümlerde bu adım zorunlu. Alesta Web olarak her zaman güncel Docker sürümü kullanmanızı öneririz.

⚠️ Dikkat / Warning:

Multi-stage build ile birlikte docker-compose.yml dosyanızda da target direktifi ile hangi stage'i build edeceğinizi belirtebilirsiniz: target: production. Development için ayrı, production için ayrı stage kullanmak (separate stages for dev/prod) mükemmel bir pattern.

? Kaynaklar ve Referanslar / Sources and References

Bu makalede kullanılan bilgiler aşağıdaki güvenilir kaynaklardan alınmıştır (information from the following reliable sources):

Alesta Web olarak tüm bilgileri doğruladık ve gerçek projelerimizde test ettik (verified and tested in real projects).

✅ Özet: Docker Multi-Stage Build ile Daha Küçük, Daha Güvenli Images! (Smaller, Safer Docker Images!)

Docker multi-stage build, modern container geliştirmenin olmazsa olmazı. Alesta Web ekibi olarak yıllardır önerdiğimiz bu teknik (we have recommended this technique for years), hem image boyutunu dramatik ölçüde küçültüyor hem de security posture'ı iyileştiriyor.

Hızlı Özet / Quick Summary:

  • ✅ Multi-stage build ile image boyutu %80-98 küçülüyor (80-98% size reduction)
  • ✅ Builder stage'deki dev tools production'a taşınmıyor (dev tools not in production)
  • ✅ Tek Dockerfile, temiz yapı (single Dockerfile, clean structure)
  • ✅ CI/CD pipeline hızlanıyor (faster CI/CD pipeline)
  • ✅ Kubernetes pod startup süresi düşüyor (faster Kubernetes pod startup)

Sorularınız mı var? alestaweb.com üzerinden bize ulaşabilirsiniz. Alesta Web DevOps ekibi, Docker ve Kubernetes projelerinizde yanınızda!

Faydalı Linkler / Useful Links:

© 2026 AlestaWeb - Tüm hakları saklıdır. / All rights reserved.

WM Tools
💫

WebMaster Tools

15 Profesyonel Araç