Docker Compose Detaylı Rehber
Docker Compose, çoklu container uygulamalarını tanımlamak ve çalıştırmak için kullanılan güçlü bir araçtır. Bu rehber, temel kullanımdan production-grade konfigürasyonlara kadar her şeyi kapsar.
[!IMPORTANT] Docker Compose V1 vs V2:
- V1 (Eski):
docker-compose(Python, deprecated) ❌- V2 (Yeni):
docker compose(Go, Docker CLI plugin) ✅Bu rehber Compose V2 syntax'ını kullanır. V1 artık deprecated, V2 kullanın!
1. Docker Compose Nedir? 🤔
Kısa Cevap: Docker Compose, birden fazla container'ı tek bir YAML dosyasıyla yönetmenizi sağlar.
Uzun Cevap: Modern uygulamalar genellikle tek bir servisten oluşmaz:
- Web uygulaması (Frontend)
- API (Backend)
- Veritabanı (PostgreSQL, MySQL)
- Cache (Redis)
- Reverse Proxy (Nginx)
- Monitoring (Prometheus, Grafana)
Tüm bunları elle (docker run ...) yönetmek kabus olur. Compose, tüm bu servisleri tek bir dosyada tanımlamanızı ve tek bir komutla yönetmenizi sağlar.
2. Temel Yapı ve Syntax 📝
2.1. Minimal Örnek
[!WARNING]
version:Artık Obsolete! Docker Compose V2'deversion:key'i tamamen görmezden geliniyor. Belirtmenize gerek yok, hatta Docker resmi olarak kaldırmanızı öneriyor.
Bu kadar! docker compose up -d dediğinizde Nginx ayağa kalkar.
2.2. Gerçek Dünya Örneği (Full-Stack App)
# Modern syntax (version key yok)
services:
# Frontend (React/Next.js)
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=http://backend:5000
depends_on:
- backend
restart: unless-stopped
# Backend (Node.js/Python/.NET)
backend:
build: ./backend
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
- REDIS_URL=redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- ./backend/uploads:/app/uploads
restart: unless-stopped
# PostgreSQL Database
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# Redis Cache
cache:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
# Nginx Reverse Proxy
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
depends_on:
- frontend
- backend
restart: unless-stopped
volumes:
postgres_data:
redis_data:
3. Servis Tanımlama (Services) 🔧
3.1. Image vs Build
Hazır Image Kullanma:
Kendi Image'ınızı Build Etme:
services:
api:
build:
context: ./backend # Dockerfile'ın bulunduğu klasör
dockerfile: Dockerfile # Dockerfile adı (varsayılan: Dockerfile)
args: # Build-time değişkenler
NODE_ENV: production
target: production # Multi-stage build'de hangi stage
İleri Seviye Build:
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
cache_from:
- myapp:latest
labels:
- "com.example.version=1.0"
shm_size: "2gb"
3.2. Ports (Port Mapping)
services:
web:
ports:
- "8080:80" # Host:Container
- "443:443"
- "127.0.0.1:5432:5432" # Sadece localhost'tan erişilebilir
[!WARNING] Güvenlik Uyarısı:
ports:kullanmak container'ı tüm dünyaya açar (UFW bypass eder). Sadece localhost'tan erişim istiyorsanız:127.0.0.1:8080:80
Expose (Sadece Container'lar Arası):
3.3. Environment Variables
Yöntem 1: Doğrudan Tanımlama
services:
app:
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
- DEBUG=false
Yöntem 2: .env Dosyasından Okuma
Yöntem 3: Host'tan Değişken Geçirme
3.4. Volumes (Veri Saklama)
Named Volumes (Önerilen - Production):
services:
db:
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data: # Docker tarafından yönetilir
Bind Mounts (Development):
services:
app:
volumes:
- ./src:/app/src # Host'taki ./src -> Container'daki /app/src
- ./config.yml:/app/config.yml:ro # Read-only
tmpfs (Geçici Veri):
3.5. Networks (Ağ Yönetimi)
Varsayılan Davranış: Compose otomatik olarak tüm servisleri aynı network'e koyar.
Özel Network Tanımlama:
services:
frontend:
networks:
- frontend_net
backend:
networks:
- frontend_net
- backend_net
db:
networks:
- backend_net # Sadece backend erişebilir
networks:
frontend_net:
backend_net:
İleri Seviye Network:
networks:
frontend_net:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
backend_net:
driver: bridge
internal: true # Dış dünyaya kapalı
3.6. Depends On (Başlatma Sırası)
Basit Bağımlılık:
Health Check ile Bağımlılık (Önerilen):
services:
web:
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
3.7. Restart Policies
services:
app:
restart: unless-stopped # Önerilen (production)
# Diğer seçenekler:
# restart: no # Hiçbir zaman yeniden başlatma
# restart: always # Her zaman yeniden başlat
# restart: on-failure # Sadece hata durumunda
3.8. Resource Limits (Kaynak Kısıtlama)
services:
app:
deploy:
resources:
limits:
cpus: "0.5" # Maksimum 0.5 CPU
memory: 512M # Maksimum 512MB RAM
reservations:
cpus: "0.25" # Minimum 0.25 CPU
memory: 256M # Minimum 256MB RAM
3.9. Health Checks
services:
api:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Örnekler:
# PostgreSQL
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
# MySQL
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
# Redis
healthcheck:
test: ["CMD", "redis-cli", "ping"]
# HTTP Endpoint
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"]
4. Production Best Practices 🏭
4.1. Güvenlik
1. Secrets Kullanımı:
services:
db:
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt
2. Read-Only Root Filesystem:
3. Non-Root User:
4. Security Options:
4.2. Logging
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "production"
Alternatif Drivers:
4.3. Override Pattern (Environment-Specific)
Base: docker-compose.yml
Production: docker-compose.prod.yml
services:
app:
environment:
- NODE_ENV=production
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
Kullanım:
# Development
docker compose up -d
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
5. Temel Komutlar 🎮
5.1. Başlatma ve Durdurma
# Tüm servisleri başlat (detached mode)
docker compose up -d
# Belirli servisleri başlat
docker compose up -d web db
# Rebuild ederek başlat
docker compose up -d --build
# Servisleri durdur (container'ları silmeden)
docker compose stop
# Servisleri durdur ve container'ları sil
docker compose down
# Servisleri durdur, container + volume'leri sil
docker compose down -v
# Servisleri durdur, container + image'leri sil
docker compose down --rmi all
5.2. Log ve Monitoring
# Tüm servislerin loglarını izle
docker compose logs -f
# Belirli servisin loglarını izle
docker compose logs -f web
# Son 100 satırı göster
docker compose logs --tail=100
# Kaynak kullanımını izle (sadece compose container'ları)
docker stats $(docker compose ps -q)
# Process listesi
docker compose top
5.3. Servis Yönetimi
# Çalışan servisleri listele
docker compose ps
# Servis detaylarını göster
docker compose ps --services
# Belirli servisi yeniden başlat
docker compose restart web
# Servisi durdur
docker compose stop web
# Servisi başlat
docker compose start web
# Servisi scale et (çoğalt)
docker compose up -d --scale web=3
5.4. Exec ve Shell
# Container içinde komut çalıştır
docker compose exec web sh
# Root olarak gir
docker compose exec -u root web sh
# Tek seferlik komut
docker compose exec db psql -U postgres
# Yeni container başlatıp komut çalıştır
docker compose run --rm web npm install
5.5. Temizlik
# Kullanılmayan container'ları temizle
docker compose down --remove-orphans
# Tüm sistemi temizle
docker system prune -a --volumes
6. Gerçek Dünya Örnekleri 🌍
[!TIP] Detaylı Production-Ready Örnekler: Aşağıdaki senaryolar için tam konfigürasyon dosyaları Şablonlar (Templates) bölümünde bulunabilir:
6.1. Basit Web App (Konsept)
services:
# Backend
api:
build: ./backend
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
depends_on:
db:
condition: service_healthy
restart: unless-stopped
# Database
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
volumes:
db_data:
Önemli Noktalar:
- ✅
depends_onile service_healthy kullanımı - ✅ Named volumes (production için)
- ✅ Environment variables
- ✅ Health checks
- ✅ Restart policy
6.2. Microservices (Konsept)
services:
gateway:
build: ./gateway
ports:
- "80:80"
networks:
- frontend
- backend
service-a:
build: ./services/a
expose:
- "5001"
networks:
- backend # Sadece backend network'ünde
db:
image: postgres:16-alpine
networks:
- backend # Dış dünyadan izole
networks:
frontend:
backend:
internal: true # İnternet erişimi yok
Önemli Noktalar:
- ✅ Network izolasyonu (frontend vs backend)
- ✅
internal: trueile güvenlik - ✅
exposevsportsfarkı - ✅ Gateway pattern
6.3. Development vs Production
docker-compose.yml (Base):
docker-compose.prod.yml (Override):
services:
app:
restart: unless-stopped
deploy:
resources:
limits:
memory: 1G
logging:
driver: "json-file"
options:
max-size: "10m"
Kullanım:
# Development
docker compose up -d
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
[!NOTE] Tam Stack Örnekleri İçin:
- MERN Stack → Monitoring Stack Template
- Microservices → Nginx Proxy Manager Template
- .NET + PostgreSQL → .NET Backend Template
7. Troubleshooting 🔍
7.1. Yaygın Sorunlar
Problem: Container ayağa kalkmıyor
# Logları kontrol et
docker compose logs web
# Container durumunu kontrol et
docker compose ps
# Health check durumunu kontrol et
docker inspect <container_id> | grep -A 10 Health
Problem: Network bağlantısı yok
# Network'leri listele
docker network ls
# Network detaylarını incele
docker network inspect <network_name>
# Container'ın network'ünü kontrol et
docker inspect <container_id> | grep -A 20 Networks
Problem: Volume verisi kayboldu
# Volume'leri listele
docker volume ls
# Volume detaylarını göster
docker volume inspect <volume_name>
# Volume'ü backup al
docker run --rm -v <volume_name>:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz /data
7.2. Debug Teknikleri
1. Container içine gir:
2. Yeni container başlat:
3. Network connectivity test:
4. Environment variables kontrol:
8. İleri Seviye Konular 🚀
8.1. Multi-Stage Builds ile Entegrasyon
Dockerfile:
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
docker-compose.yml:
8.2. Profiles (Conditional Services)
services:
app:
image: myapp
db:
image: postgres:16-alpine
# Sadece debug modunda çalışsın
debug-tools:
image: nicolaka/netshoot
profiles:
- debug
command: sleep infinity
Kullanım:
# Normal mod (debug-tools çalışmaz)
docker compose up -d
# Debug mod (debug-tools da çalışır)
docker compose --profile debug up -d
8.3. Extension Fields (DRY Principle)
x-common-variables: &common-env
NODE_ENV: production
LOG_LEVEL: info
x-restart-policy: &restart-policy
restart: unless-stopped
services:
web:
<<: *restart-policy
environment:
<<: *common-env
SERVICE_NAME: web
api:
<<: *restart-policy
environment:
<<: *common-env
SERVICE_NAME: api
9. Checklist: Production-Ready Compose 📋
- [ ] Secrets yönetimi - Şifreler
.envveya secrets ile - [ ] Health checks - Tüm kritik servislerde
- [ ] Resource limits - CPU/Memory limitleri tanımlı
- [ ] Restart policy -
unless-stoppedveyaalways - [ ] Logging - Log rotation konfigüre edilmiş
- [ ] Named volumes - Bind mount yerine named volume
- [ ] Network isolation - Gereksiz servislere erişim kapalı
- [ ] Read-only filesystem - Mümkünse
read_only: true - [ ] Non-root user - Container'lar root olarak çalışmıyor
- [ ] Security options -
no-new-privileges, cap_drop - [ ] Backup stratejisi - Volume backup planı var
- [ ] Monitoring - Health check ve log monitoring aktif
10. Kaynaklar 📚
💡 Pro Tip: Compose dosyanızı her zaman version control'e (Git) ekleyin, ancak
.envdosyasını asla commit etmeyin!