"Ama Benim Makinemde Çalışıyordu!"
Container teknolojilerinin (Docker) en büyük vaadi şuydu: "Bir kere paketle, her yerde çalıştır." Ancak teori ile pratik her zaman uyuşmuyor.
Local ortamınızda sorunsuz çalışan bir Docker container'ı, production'a çıktığında hafıza sınırlarını zorlayabilir, güvenlik açıklarına kapı aralayabilir veya deployment süresini uzatabilir.
Bir projede 2.3 GB olan Docker image boyutunu, sadece doğru pratikleri uygulayarak 180 MB'a düşürdük. Bu sadece diskten tasarruf değil; daha hızlı deployment, daha hızlı scaling ve daha az güvenlik riski demektir. İşte reçetesi.
Bölüm 1: Multi-stage Build Anatomisi
En büyük hata, tek aşamalı (single stage) build kullanmaktır. Kodunuzu derlemek için kullandığınız araçlara (gcc, python, node-gyp vb.) production'da ihtiyacınız yoktur.
Kötü Örnek (Single Stage):
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]Bu dosya ile oluşan image, Node.js kaynak kodlarını, npm cache'lerini ve gereksiz build araçlarını içerir. Sonuç: ~1GB+.
İyi Örnek (Multi-stage):
# Stage 1: Builder
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: Runner
FROM node:18-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
CMD ["npm", "start"]Burada "Runner" aşamasına sadece çalışması için gereken dosyaları kopyalıyoruz. Gereksiz her şey geride kalıyor. Sonuç: ~200MB.
Bölüm 2: Base Image Seçimi
Base image, binanızın temelidir.
- node:18: Tam işletim sistemi (Debian) içerir. Ağırdır (1GB), güvenlidir ama çok fazla gereksiz paket barındırır.
- node:18-slim: Gereksiz paketlerden arındırılmıştır. Production için idealdir.
- node:18-alpine: Çok hafiftir (50MB) ama
glibcyerinemuslkütüphanesini kullanır. Bazı C++ modülleri veya Python kütüphaneleri burada çalışmayabilir. Test etmeden kullanmayın. - Distroless: Google'ın geliştirdiği, içinde Shell (bash) bile olmayan, sadece uygulamanızın çalışması için gereken minimumu içeren image'lar. En güvenlisi ama debug etmesi zordur.
Bölüm 3: Layer Caching Stratejisi
Docker, her satırı bir katman (layer) olarak cache'ler. Dosyaların değişme sıklığına göre sıralama yapmak, build süresini dakikalardan saniyelere düşürür.
Yanlış Sıralama:
COPY . .
RUN npm installKodunuzda 1 karakter bile değişse, Docker "COPY . ." satırının değiştiğini görür ve sonraki tüm adımları (npm install dahil) baştan yapar.
Doğru Sıralama:
COPY package*.json ./
RUN npm install
COPY . .package.json değişmediği sürece npm install adımı cache'ten gelir. Kodunuzu değiştirip deploy ettiğinizde build süreniz sadece kopyalama süresi kadar olur.
Bölüm 4: Güvenlik Şakaya Gelmez (Hardening)
-
Non-root User: Docker varsayılan olarak
rootkullanıcısıyla çalışır. Bu büyük bir risktir. Uygulamanızı kısıtlı bir kullanıcıyla çalıştırın.USER node -
Secrets Management: API key'leri veya DB şifrelerini asla Dockerfile içine
ENVolarak yazmayın. Build history'de görünür. Runtime'da enjekte edin veyaDocker Secrets/Vaultkullanın. -
Trivy Scan: CI/CD pipeline'ınıza mutlaka bir güvenlik tarayıcı ekleyin.
trivy image my-appkomutu size "Bu image'da 3 kritik, 12 orta seviye açık var" raporunu verir.
Bölüm 5: Production Runtime İpuçları
- Resource Limits: Container'ınızın tüm sunucuyu sömürmesini engelleyin. Kubernetes veya Docker Compose dosyanızda limit verin:
deploy: resources: limits: cpus: '0.50' memory: 512M - Restart Policy:
restart: alwaysveyaon-failurekullanarak uygulamanız çöktüğünde Docker'ın onu tekrar ayağa kaldırmasını sağlayın. - Logging: Varsayılan
json-fileloglama sürücüsü disk alanını doldurabilir. Log rotasyonu (log-opt) ayarlayın.
Sonuç: Konteynerler Çöp Kutusu Değildir
Docker, "her şeyi içine atıp çalıştırdığımız" bir çöplük değildir. Özenle paketlenmesi gereken bir dağıtım birimidir.
Dockerfile Review Checklist:
- [ ] Multi-stage build kullanıldı mı?
- [ ] Gereksiz dosyalar
.dockerignoreile dışlandı mı? - [ ] Root yetkileri alındı mı (USER node)?
- [ ] Base image spesifik bir versiyona sabitlendi mi (node:18.16.0-slim)?
- [ ] Güvenlik taraması yapıldı mı?
Eğer Kubernetes, ECS veya Docker Swarm üzerinde koşan mimariniz sürekli alarm veriyorsa, sorun orkestrasyonda değil, belki de temelde, yani Docker image'ınızda olabilir. Destek almak isterseniz buradayım.
