DEVOPS // DOCKERD::02 BAŞLANGIÇ+
22m READCOMPLETION: 87%ID::DOC-101

DOCKER: KONTEYNERİZASYON VE COMPOSE

Dockerfile, multi-stage build, Docker Compose ve production güvenliği

Docker, uygulamaları ve tüm bağımlılıklarını izole "container"lar içinde çalıştıran platformdur. "Bende çalışıyordu" sorununu ortadan kaldırır; geliştirme, test ve üretim ortamlarını birbirine eşitler.

Temel Kavramlar

KavramAçıklama
ImageContainer'ın şablonu; değiştirilemez katmanlar
ContainerImage'dan oluşturulan çalışan örnek
DockerfileImage'ı tarif eden talimatlar dosyası
RegistryImage'ların depolandığı yer (Docker Hub, GHCR)
VolumeContainer dışında kalıcı veri depolama
NetworkContainer'lar arası iletişim katmanı

İlk Container

Dockerfile Yazımı

// DOCKERFILE //
# Node.js uygulaması için Dockerfile
# Base image — mümkün olan en küçüğünü seçin
FROM node:22-alpine AS base
 
# Çalışma dizini
WORKDIR /app
 
# Bağımlılıkları önce kopyala — Docker cache için
COPY package*.json ./
 
# Dependencies katmanı
FROM base AS deps
RUN npm ci --only=production
 
# Development dependencies (build için)
FROM base AS build-deps
RUN npm ci
 
# Build aşaması
FROM build-deps AS builder
COPY . .
RUN npm run build
 
# Production image — mümkün olan en küçük
FROM node:22-alpine AS runner
WORKDIR /app
 
# Güvenlik: root olmayan kullanıcı
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
 
# Sadece gerekli dosyaları kopyala
COPY --from=deps    /app/node_modules ./node_modules
COPY --from=builder /app/dist         ./dist
COPY --from=builder /app/package.json ./
 
# Port ve başlatma
EXPOSE 3000
ENV NODE_ENV=production
 
CMD ["node", "dist/server.js"]

.dockerignore

// PLAINTEXT //
# .dockerignore — .gitignore gibi ama Docker için
node_modules/
dist/
.git/
.gitignore
*.log
.env
.env.*
README.md
Dockerfile*
docker-compose*.yml
coverage/
__tests__/
.nyc_output/

Image Build ve Push

Docker Compose

// YAML //
# docker-compose.yml — çok servisi birlikte yönet
services:
  app:
    build:
      context: .
      target: runner       # Multi-stage build hedefi
    container_name: blog-app
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:secret@db:5432/blogdb
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    volumes:
      - uploads:/app/uploads
    restart: unless-stopped
    networks:
      - iç-ağ
 
  db:
    image: postgres:16-alpine
    container_name: blog-db
    environment:
      POSTGRES_USER:     postgres
      POSTGRES_PASSWORD: secret
      POSTGRES_DB:       blogdb
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - iç-ağ
 
  cache:
    image: redis:7-alpine
    container_name: blog-cache
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - iç-ağ
 
  nginx:
    image: nginx:alpine
    container_name: blog-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    networks:
      - iç-ağ
 
volumes:
  postgres-data:
  redis-data:
  uploads:
 
networks:
  iç-ağ:
    driver: bridge

Volume ve Veri Yönetimi

// BASH //
# Named volume oluştur
docker volume create uygulama-verisi
 
# Volume listesi
docker volume ls
 
# Volume içeriğini incele
docker run --rm -v uygulama-verisi:/data alpine ls -la /data
 
# Volume yedekle
docker run --rm \
  -v uygulama-verisi:/data \
  -v $(pwd)/yedek:/yedek \
  alpine tar czf /yedek/yedek-$(date +%Y%m%d).tar.gz /data
 
# Bind mount — geliştirme için (hot reload)
docker run -v $(pwd)/src:/app/src -p 3000:3000 uygulama:dev

Network Yönetimi

// BASH //
# Custom network oluştur
docker network create --driver bridge uygulama-agi
 
# Container'ı ağa bağla
docker run --network uygulama-agi --name api uygulama:latest
 
# Container'dan container'a erişim (container ismi ile)
# api container içinden db'ye:
curl http://db:5432
 
# Network'ü incele
docker network inspect uygulama-agi

Geliştirme Ortamı (Dev Compose)

// YAML //
# docker-compose.dev.yml — sadece geliştirme için
services:
  app:
    build:
      context: .
      target: build-deps    # Dev bağımlılıkları da yükle
    command: npm run dev     # Hot reload
    volumes:
      - .:/app               # Kaynak kodu bind mount
      - /app/node_modules    # node_modules override'ı engelle
    environment:
      - NODE_ENV=development
    ports:
      - "3000:3000"
      - "9229:9229"          # Node.js debugger

Sonuç

Docker, uygulamanızı ve tüm bağımlılıklarını kapsülleyerek her ortamda aynı şekilde çalışmasını sağlar. Multi-stage build, Compose ve Volume yönetimini kavradığınızda geliştirme ve dağıtım süreçleriniz dramatik şekilde kolaylaşır. Bir sonraki derste Kubernetes ile container orchestration'a giriş yapacağız.