Compose Profilleri, Override ve Ortam Yönetimi
Bu bölümün son dersine geldik. Şimdiye kadar Compose ile projeler kurmayı ve docker-compose.yml anatomisini öğrendik. Ama gerçek hayatta bir proje sadece bir ortamda çalışmaz — development, staging, production, test... Her ortamın farklı ihtiyaçları var. Development'ta debug araçları lazım, production'da resource limitleri, test'te geçici veritabanı.
Peki aynı projeyi farklı ortamlarda nasıl çalıştırırsın? Her ortam için ayrı Compose dosyası mı yazarsın? İşte burada profiller ve override dosyaları devreye giriyor.
Bir oteli düşün. Standart oda herkese aynı: yatak, banyo, TV. Ama "business paketi" seçersen çalışma masası eklenir. "Spa paketi" seçersen jakuzi. Otel aynı, odalar aynı — aktif ettiğin profil ekstra ne alacağını belirler. Compose profilleri tam böyle çalışır.
Compose Profilleri — Opsiyonel Servisler
Profiller, servisleri gruplandırıp isteğe bağlı aktif etmeni sağlar. Profil tanımlanmayan servisler her zaman çalışır — bunlar projenin çekirdeği. Profilli servisler ise sadece o profil aktifken çalışır.
services:
# Her zaman çalışanlar (profil yok)
api:
build: ./api
ports:
- "3000:3000"
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
# Debug profili
adminer:
image: adminer:latest
ports:
- "8080:8080"
profiles:
- debug
mailhog:
image: mailhog/mailhog
ports:
- "8025:8025"
- "1025:1025"
profiles:
- debug
# Monitoring profili
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
profiles:
- monitoring
grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
profiles:
- monitoring
# Test profili
test-runner:
build:
context: ./api
target: test
command: npm test
depends_on:
test-db: { condition: service_healthy }
profiles:
- test
test-db:
image: postgres:16-alpine
environment:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
tmpfs:
- /var/lib/postgresql/data # RAM'de — hızlı, geçici
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test"]
interval: 5s
timeout: 3s
retries: 5
profiles:
- test
volumes:
pgdata:Kullanımı çok basit:
# Sadece temel servisler (api + db)
docker compose up -d
# adminer, mailhog, prometheus, grafana ÇALIŞMAZ
# Debug araçlarıyla birlikte
docker compose --profile debug up -d
# api + db + adminer + mailhog
# Monitoring ile birlikte
docker compose --profile monitoring up -d
# api + db + prometheus + grafana
# Her şeyi birden
docker compose --profile debug --profile monitoring up -d
# api + db + adminer + mailhog + prometheus + grafana
# Testleri çalıştır
docker compose --profile test run --rm test-runnerTest profili çok akıllıca tasarlanmış. test-db servisi tmpfs kullanıyor — veritabanı RAM'de çalışıyor, disk I/O yok, çok hızlı. Test bitince her şey silinir. Ve test-runner'ın depends_on'ı sayesinde test-db otomatik başlatılır.
Profili environment variable ile de aktifleştirebilirsin:
export COMPOSE_PROFILES=debug,monitoring
docker compose up -dYa da .env dosyasında:
COMPOSE_PROFILES=debugOverride Dosyaları — Ortam Bazlı Konfigürasyon
Override dosyaları, temel Compose dosyasının üzerine ek konfigürasyon "yamar." Aynı servis için farklı ayarları ortam bazında tanımlarsın.
Otomatik Override
docker-compose.override.yml adında bir dosya varsa, Compose onu otomatik yükler:
# docker-compose.yml (base — her ortamda geçerli)
services:
api:
build: ./api
environment:
NODE_ENV: production
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:# docker-compose.override.yml (development — OTOMATİK yüklenir)
services:
api:
build:
target: development
volumes:
- ./api/src:/app/src
- /app/node_modules
ports:
- "3000:3000"
- "9229:9229"
environment:
NODE_ENV: development
DEBUG: "app:*"
db:
ports:
- "5432:5432"# Override otomatik uygulanır
docker compose up -d
# api: development stage, hot reload, debug port
# Override'ı ATLAYARAK production ayarlarıyla başlat
docker compose -f docker-compose.yml up -dBu çok pratik — development'ta docker compose up demen yeter, override otomatik gelir.
Manuel Override Dosyaları
Farklı ortamlar için ayrı override dosyaları oluştur:
# docker-compose.staging.yml
services:
api:
build: { target: production }
environment:
NODE_ENV: staging
LOG_LEVEL: debug
deploy:
resources:
limits: { memory: 256M }# docker-compose.prod.yml
services:
api:
build: { target: production }
deploy:
replicas: 3
resources:
limits: { memory: 512M, cpus: "1.0" }
logging:
driver: json-file
options: { max-size: "50m", max-file: "10" }# Staging
docker compose -f docker-compose.yml -f docker-compose.staging.yml up -d
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dOverride Birleştirme Kuralları
Bu kuralları bilmek önemli çünkü bazen beklenmedik sonuçlar üretir:
Tek değerler (image, command, entrypoint) → Override üzerine yazar. Map'ler (environment, labels) → Aynı key üzerine yazar, yeni key eklenir. Listeler (ports, volumes) → Override'daki öğeler eklenir (replace etmez!).
Örnek:
# Base:
services:
api:
ports: ["3000:3000"]
environment:
NODE_ENV: production
LOG_LEVEL: warn
# Override:
services:
api:
ports: ["9229:9229"] # EKLENIR (replace değil!)
environment:
NODE_ENV: development # ÜZERINE YAZAR
DEBUG: "*" # YENİ — eklenirSonuç: ports → ["3000:3000", "9229:9229"], environment → {NODE_ENV: development, LOG_LEVEL: warn, DEBUG: "*"}.
Final konfigürasyonu görmek için:
docker compose -f docker-compose.yml -f docker-compose.prod.yml configMakefile ile Kısayollar
Her seferinde uzun docker compose -f ... -f ... komutları yazmak yorucu. Makefile ile kısayollar oluştur:
.PHONY: dev staging prod test logs clean
COMPOSE = docker compose -f docker-compose.yml
dev:
$(COMPOSE) -f docker-compose.override.yml up -d
@echo "Dev: http://localhost:3000"
staging:
$(COMPOSE) -f docker-compose.staging.yml --env-file .env.staging up -d --build
prod:
$(COMPOSE) -f docker-compose.prod.yml --env-file .env.production up -d --build
test:
$(COMPOSE) --profile test run --rm test-runner
logs:
$(COMPOSE) logs -f $(SVC)
shell:
$(COMPOSE) exec $(SVC) sh
migrate:
$(COMPOSE) run --rm api node scripts/migrate.js
clean:
$(COMPOSE) down -v --rmi local
status:
$(COMPOSE) psKullanımı:
make dev # Development ortamını başlat
make prod # Production deploy
make test # Testleri çalıştır
make logs SVC=api # API loglarını izle
make shell SVC=db # Veritabanı shell'i aç
make migrate # Migration çalıştırCompose Watch — Dosya İzleme (v2.22+)
Modern Docker Compose'un çok kullanışlı bir özelliği: dosya değişikliğini otomatik algılayıp uygun aksiyonu almak.
services:
api:
build: ./api
develop:
watch:
- action: sync
path: ./api/src
target: /app/src
ignore: ["**/*.test.js"]
- action: rebuild
path: ./api/package.json
- action: sync+restart
path: ./api/config
target: /app/configdocker compose watchBu modda:
src/server.jsdeğişti → dosyayı container'a sync et (rebuild yok, çok hızlı)package.jsondeğişti → image'ı rebuild et, container'ı yeniden oluşturconfig/app.ymldeğişti → dosyayı sync et ve container'ı restart et
Bind mount'a alternatif olarak watch daha akıllı — her dosya değişikliği için farklı aksiyon tanımlayabiliyorsun.
COMPOSE_FILE Environment Variable
# Her seferinde -f yazmak yerine
export COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml
docker compose up -d
# .env dosyasında da tanımlayabilirsin
COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml
COMPOSE_PROJECT_NAME=myapp # Volume ve network prefix'i
COMPOSE_PROFILES=monitoringGerçek Dünya Ortam Yapısı
project/
├── docker-compose.yml # Base config
├── docker-compose.override.yml # Dev (otomatik)
├── docker-compose.staging.yml # Staging
├── docker-compose.prod.yml # Production
├── .env # Dev variables
├── .env.example # Template (git'e commit)
├── .env.production # Prod variables (commit ETME)
├── Makefile # Kısayollar
└── .gitignore# .gitignore
.env
.env.production
.env.staging
!.env.example
docker-compose.override.yml # Her developer kendi override'ını yazsınYaygın Hatalar
Override otomatik yükleniyor: Production sunucusunda docker-compose.override.yml varsa otomatik yüklenir ve debug araçları açılır! Çözüm: Production'da açıkça dosya belirt veya override dosyasını gitignore'a ekle.
Host env, .env'yi override eder: export DB_PASS=old yaptıysan ve .env'de DB_PASS=new varsa, old değeri kullanılır. Host environment her zaman önce gelir. unset DB_PASS ile temizle.
Profilli bağımlılık: Profil'siz bir servis, profilli bir servise depends_on ile bağlanamaz — profil aktif edilmeden o servis başlatılamaz.
Bu Derste Ne Öğrendik?
Profiller ile servisleri grupla:
--profile debug,--profile monitoring,--profile test.Override dosyaları ile ortam bazlı konfigürasyon: base + dev/staging/prod.
docker-compose.override.ymlotomatik yüklenir — production'da dikkatli ol.Override'da listeler eklenir (replace etmez), map'lerdeki aynı key üzerine yazılır.
Makefile ile günlük komutlara kısayol oluştur.
Compose Watch ile development'ta dosya değişikliklerini akıllıca yönet.
Host env >
--env-file>.env— öncelik sırasını bil.
Bu, Docker Compose bölümünün son dersiydi. Artık birden fazla container'ı profesyonelce yönetmeyi biliyorsun. Sonraki bölümde Docker image'larını optimize etmeyi öğreneceğiz — multi-stage builds, layer caching ve image boyut küçültme.
AI Asistan
Sorularını yanıtlamaya hazır