Docker ve Docker Compose: Geliştirmeden Production'a
Bu rehberde ne öğreneceksiniz?
Bu yazı bir haber özeti değil; adım adım uygulayabileceğiniz bir öğretici makale (tutorial) formatındadır. Her bölümün sonunda pratik çıkarımlar ve üretim ortamında karşılaşacağınız senaryolar yer alır.
- Multi-stage Dockerfile ile küçük production image üretmek
- Compose ile local full-stack ortam kurmak
- Healthcheck ve non-root user ile güvenliği artırmak
- CI pipeline'da image build ve scan otomatikleştirmek
Ön koşullar
Rehberi verimli takip etmek için aşağıdaki bilgilere aşina olmanız önerilir. Eksik hissettiğiniz konularda ilgili bölümde ek kaynak ipuçları bulacaksınız.
- Terminal kullanımı
- Temel ağ (port, volume) kavramı
- Next.js uygulamasını local çalıştırma deneyimi
Güncellik ve teknoloji yığını
Makale 2026 itibarıyla güncellenmiştir. Örnekler ve API referansları şu yığınla uyumludur: Docker 27+, Docker Compose v2, Node.js 22 alpine, PostgreSQL 16. Eski sürüm dokümantasyonu ile karıştırmamak için major versiyon farklarını özellikle belirttik.
Framework sürümleri hızla değişir; kalıcı olan prensipler (güvenlik, katman ayrımı, ölçüm) bu rehberin omurgasını oluşturur.
Bölüm 1: Multi-stage Dockerfile
Build bağımlılıkları runtime image'a girmemeli. İki aşama: deps + build, sonra yalnızca standalone output.
Adım adım uygulama
Aşağıdaki sırayı takip edin. Her adımı tamamlamadan bir sonrakine geçmeyin; özellikle güvenlik ve veri katmanı adımları atlanmamalıdır.
- deps stage: yarn install --frozen-lockfile
- builder: next build (standalone output etkin)
- runner: non-root user, yalnızca .next/standalone kopyala
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S nodejs && adduser -S nextjs -G nodejs
COPY --from=builder /app/.next/standalone ./
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
İpucu: next.config output: "standalone" production image boyutunu ciddi düşürür.
Bölüm 2: Docker Compose local stack
Tek komutla app + postgres. Volume ile veri kalıcılığı; network ile servis izolasyonu.
Adım adım uygulama
Aşağıdaki sırayı takip edin. Her adımı tamamlamadan bir sonrakine geçmeyin; özellikle güvenlik ve veri katmanı adımları atlanmamalıdır.
- compose.yml oluşturun.
docker compose up --buildile ayağa kaldırın.- Migration'ı entrypoint veya ayrı init job ile çalıştırın.
services:
db:
image: postgres:16-alpine
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 5
app:
build: .
depends_on:
db:
condition: service_healthy
environment:
POSTGRES_PRISMA_URL: postgresql://postgres:postgres@db:5432/postgres
Bölüm 3: Production checklist
Registry'ye push öncesi: Trivy scan, secret env, read-only filesystem, resource limit.
Dikkat: .env dosyasını image layer'ına COPY etmeyin — build-time ARG ile de olsa risklidir.
Bölüm 4: Supply chain ve imaj güvenliği
Base image pin, distroless ve CVE taraması (Trivy, Grype) pipeline'a eklenmeli.
Production ortamında Docker ile ilgili en sık görülen sorun, geliştirme ortamındaki varsayımların (küçük veri seti, tek kullanıcı, sıcak cache) canlı trafikte çökmemesidir. Bu yüzden her değişiklikten önce yük testi veya en azından p95 latency ölçümü yapın.
Structured logging (request id, route, süre, kullanıcı id’si — PII olmadan) ve hata oranı alarmları, sorunları kullanıcı şikayetinden önce yakalamanızı sağlar. Log’da stack trace tutun; kullanıcıya generic mesaj gösterin.
Dokümantasyonu kod ile birlikte güncelleyin: README, ADR (Architecture Decision Record) veya ekip wiki’sinde “neden bu kararı aldık?” sorusunun cevabı gelecekteki sizin en büyük yardımcınızdır.
- Non-root USER
- Read-only root filesystem mümkünse
- Secret'ları env file yerine runtime inject
Sık yapılan hatalar
Aşağıdaki tuzaklar eğitim ortamlarında nadiren, production'da ise pahalıya mal olur. Code review checklist'inize eklemenizi öneririz.
- Root user ile container çalıştırmak
- latest tag ile production deploy
- Healthcheck olmadan depends_on kullanmak
Pratik alıştırmalar
Okumak yeterli değildir; öğrenmeyi pekiştirmek için küçük bir side-project veya mevcut kod tabanınızda şu görevleri uygulayın:
- Local compose ile prisma migrate ve seed çalıştırın
- Image boyutunu multi-stage öncesi/sonrası karşılaştırın
Özet ve sonraki adımlar
Bu rehberdeki prensipleri tek seferde tüm projeye uygulamaya çalışmayın. Önce tek bir route veya modül seçin, ölçün, sonra yaygınlaştırın.
- GitHub Actions ile build-push pipeline kurun
- Kubernetes öğreticisine geçin