Ana içeriğe geç
Kategoriye Dön

Docker Compose Rehberi: Çok Konteynerli Uygulama Yönetimi

Docker Compose ile çok konteynerli uygulama tanımlama, servis bağımlılıkları, environment variables, health check, scaling ve production deployment. Kapsamlı rehber.

Okuma süresi: 16 dk DevOps & Otomasyon
docker-composedockerkonteyneryamldevopsmikroservisdeployment

İçindekiler

Docker Compose Rehberi: Çok Konteynerli Uygulama Yönetimi

Docker Compose, birden fazla Docker konteynerini tek bir YAML dosyasıyla tanımlamanızı ve yönetmenizi sağlayan bir araçtır. Mikroservis mimarileri, web uygulamaları ve geliştirme ortamları için vazgeçilmezdir.

Docker Compose Nedir?

Docker Compose ile şunları yapabilirsiniz:

  • Birden fazla servisi tek bir docker-compose.yml dosyasında tanımlama
  • Servisler arası bağımlılıkları yönetme
  • Ağ ve volume yapılandırmalarını merkezi olarak yönetme
  • Tek komutla tüm stack'i başlatma/durdurma

Docker Compose v2, docker compose (tire olmadan) komutuyla çalışır ve Docker CLI'ye entegre edilmiştir. Eski docker-compose komutu hâlâ desteklenmektedir.

Temel docker-compose.yml Yapısı

hljs yaml
version: '3.9'

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: gizli_sifre
      MYSQL_DATABASE: uygulamam
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  db_data:

Servisler, Volumes ve Networks

Servis Tanımlama

hljs yaml
services:
  uygulama:
    build:
      context: ./app
      dockerfile: Dockerfile
    image: uygulamam:latest
    container_name: uygulama-konteyner
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
      DB_HOST: veritabani
    depends_on:
      veritabani:
        condition: service_healthy
    networks:
      - uygulama-agi
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

Volume Tanımlama

hljs yaml
volumes:
  # Named volume (Docker tarafından yönetilir)
  db_data:
    driver: local

  # Harici volume (önceden oluşturulmuş)
  mevcut_volume:
    external: true

  # Özel driver seçenekleri
  nfs_volume:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.1.100,rw
      device: ":/nfs/paylasim"

Network Tanımlama

hljs yaml
networks:
  # Varsayılan bridge ağı
  uygulama-agi:
    driver: bridge

  # Özel subnet ile
  ozel-ag:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

  # Harici ağ
  mevcut-ag:
    external: true

depends_on ve Healthcheck

depends_on ile servis başlangıç sırasını kontrol edebilirsiniz:

hljs yaml
services:
  web:
    image: nginx:alpine
    depends_on:
      api:
        condition: service_healthy
      db:
        condition: service_healthy

  api:
    build: ./api
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: sifre
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

depends_on yalnızca başlangıç sırasını kontrol eder. condition: service_healthy kullanmadan servisin hazır olduğunu garanti edemezsiniz.

Environment Variables ve env_file

Doğrudan Tanımlama

hljs yaml
services:
  uygulama:
    image: myapp:latest
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DB_HOST=veritabani
      - DB_PORT=5432

.env Dosyası Kullanımı

hljs yaml
services:
  uygulama:
    image: myapp:latest
    env_file:
      - .env
      - .env.production

.env dosyası:

hljs bash
# .env
NODE_ENV=production
DB_HOST=veritabani
DB_PORT=5432
DB_NAME=uygulamam
DB_USER=kullanici
DB_PASS=gizli_sifre
JWT_SECRET=cok_gizli_anahtar
REDIS_URL=redis://redis:6379

.env dosyasını .gitignore'a ekleyin. Hassas bilgileri asla Git'e commit etmeyin.

Scaling (--scale)

Docker Compose ile servisleri yatay olarak ölçeklendirebilirsiniz:

hljs bash
# api servisini 3 instance ile başlat
docker compose up -d --scale api=3

# Çalışan instance sayısını değiştir
docker compose up -d --scale api=5

# Belirli bir servisi ölçeklendir
docker compose scale api=3 worker=2

Scaling için load balancer yapılandırması:

hljs yaml
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - api

  api:
    build: ./api
    # Port tanımlamayın - nginx yönlendirecek
    expose:
      - "3000"
    environment:
      NODE_ENV: production

Override Dosyaları

Farklı ortamlar için override dosyaları kullanın:

hljs yaml
# docker-compose.override.yml (geliştirme)
services:
  uygulama:
    build:
      context: .
      target: development
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      NODE_ENV: development
    command: npm run dev

  db:
    ports:
      - "5432:5432"  # Geliştirmede dışarıya aç
hljs yaml
# docker-compose.prod.yml (production)
services:
  uygulama:
    image: registry.example.com/uygulamam:latest
    restart: always
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '1.0'
          memory: 1G

Kullanım:

hljs bash
# Geliştirme (override otomatik uygulanır)
docker compose up -d

# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Production Best Practices

Tam Production Örneği

hljs yaml
version: '3.9'

services:
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - certbot_data:/etc/letsencrypt:ro
      - ./nginx/html:/var/www/html:ro
    depends_on:
      - api
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  api:
    image: registry.example.com/api:${APP_VERSION:-latest}
    env_file: .env.production
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: always
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 128M

  db:
    image: postgres:15-alpine
    env_file: .env.production
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./db/init:/docker-entrypoint-initdb.d:ro
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 1G

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  postgres_data:
  redis_data:
  certbot_data:

networks:
  default:
    driver: bridge

Temel Komutlar

hljs bash
# Tüm servisleri başlat
docker compose up -d

# Belirli servisi başlat
docker compose up -d api

# Logları takip et
docker compose logs -f
docker compose logs -f api

# Servisleri durdur
docker compose down

# Servisleri durdur ve volume'ları sil
docker compose down -v

# Servisleri yeniden başlat
docker compose restart api

# Servis durumunu görüntüle
docker compose ps

# Serviste komut çalıştır
docker compose exec api bash

# Image'ları yeniden oluştur
docker compose build --no-cache
docker compose up -d --build

# Konfigürasyonu doğrula
docker compose config

Sonuç

Docker Compose, çok konteynerli uygulamaları yönetmenin en pratik yoludur. Geliştirmeden production'a kadar tutarlı bir ortam sağlar. Override dosyaları ile farklı ortamlar için esnek yapılandırma yapabilir, healthcheck ve depends_on ile servis bağımlılıklarını güvenle yönetebilirsiniz.