Docker Compose ile Çoklu Konteyner Kurulum
Tek bir konteyner çalıştırmak kolay. İşin zorlaştığı yer, uygulamanın yanına bir veritabanı, bir önbellek ve belki bir ters proxy eklediğiniz an. Her biri için ayrı ayrı docker run komutu yazmak, portları ve ağ isimlerini hatırlamak zamanla dayanılmaz olur. Docker Compose tam bu noktada devreye girer: tüm servisleri tek bir YAML dosyasında tanımlarsınız, tek komutla ayağa kaldırırsınız.
Aşağıdaki adımları kendi makinenizde uygulayarak ilerleyin. Konteyner mantığına yeniyseniz önce temel kavramları (imaj, konteyner, volume) tazelemeniz işinizi kolaylaştırır.
Compose Dosyasını Sıfırdan Kurmak
Compose, proje kökündeki compose.yaml (veya eski adıyla docker-compose.yml) dosyasını okur. Dosya, servislerin listesinden oluşur. Her servis bir imajdan türeyen bir konteynerdir.
Dizin yapısı ve ilk servis
Basit bir web + veritabanı senaryosu için şu yapıyı kurun:
- proje/ — kök dizin
- proje/compose.yaml — servis tanımları
- proje/app/ — uygulama kodu ve Dockerfile
- proje/.env — parola ve port gibi değişkenler
YAML dosyasında girintiler boşlukla verilir, sekme karakteri hata üretir. Kök seviyede services anahtarı bulunur. Altına servis adını yazarsınız: örneğin web ve db. Servis adı aynı zamanda ağ içindeki host adıdır. Yani uygulamanız veritabanına db:5432 adresiyle bağlanır, localhost ile değil. Yeni başlayanların en sık takıldığı yer burasıdır.
Sık kullanılan anahtarlar
| Anahtar | Ne yapar |
|---|---|
| image | Hazır imajı çeker (örn. postgres:16) |
| build | Belirtilen dizindeki Dockerfile'ı derler |
| ports | Host portunu konteyner portuna bağlar (8080:80) |
| environment | Ortam değişkenlerini geçirir |
| volumes | Kalıcı veri veya kod bağlar |
| depends_on | Başlatma sırasını belirler |
| restart | Çökme sonrası davranış (unless-stopped) |
Veritabanı servisine mutlaka adlandırılmış bir volume verin. Aksi halde konteyneri sildiğinizde veriler de gider. Kök seviyeye ayrı bir volumes bloğu ekleyip orada volume adını tanımlarsınız.
Gizli bilgileri .env dosyasına taşımak
Parolayı YAML içine gömmeyin. .env dosyasına DB_PASSWORD=... şeklinde yazın, YAML içinde ${DB_PASSWORD} olarak kullanın. Compose bu dosyayı otomatik okur. .env dosyasını da .gitignore listesine ekleyin; şifre saklama alışkanlıklarını ciddiye almak, sürüm geçmişine sızmış bir parolayı temizlemekten çok daha kolaydır.
Günlük Kullanım ve Sorun Giderme
Dosya hazır olduğunda iş komutlara geçer. Compose komutlarının tamamı, dosyanın bulunduğu dizinde çalıştırılır.
Temel komut seti
- docker compose up -d — servisleri arka planda başlatır.
- docker compose ps — hangi servis ayakta, hangi port açık gösterir.
- docker compose logs -f web — tek servisin loglarını canlı izler.
- docker compose exec db psql -U postgres — çalışan konteynerin içine girip komut çalıştırır.
- docker compose down — konteynerleri ve ağı kaldırır, volume'lara dokunmaz.
- docker compose down -v — volume'ları da siler. Sıfırdan başlamak istediğinizde kullanın.
Kod değiştirdiğinizde docker compose up -d --build demeniz gerekir. Sadece up yazarsanız Compose eski imajı kullanmaya devam eder ve "değişikliğim neden görünmüyor" sorusuna saatler harcarsınız.
Bağımlılık ve sağlık kontrolü
depends_on yalnızca konteynerin başlatılmasını bekler; içindeki servisin hazır olmasını beklemez. Veritabanı henüz bağlantı kabul etmiyorken uygulama ayağa kalkar ve çöker. Çözüm iki katmanlı:
- Veritabanı servisine healthcheck ekleyin. PostgreSQL için pg_isready, MySQL için mysqladmin ping uygun bir test komutudur.
- Uygulama servisinde depends_on altında condition: service_healthy kullanın.
- Yine de uygulama kodunda bağlantı için basit bir yeniden deneme döngüsü bulundurun. En sağlam yol budur.
Tipik hatalar ve hızlı çözümler
- port is already allocated: Host portu meşgul. Sol taraftaki numarayı değiştirin, örneğin 8081:80.
- connection refused: Servis adı yerine localhost kullanmışsınızdır. Adresi servis adına çevirin.
- Permission denied (bağlı dizinlerde): Konteyner kullanıcısının UID'i host kullanıcınızla uyuşmuyor. Terminalde id -u ile kontrol edip user anahtarını ayarlayın.
- Değişiklik yansımıyor: Kaynak kodu volume ile bağlamamış olabilirsiniz. Geliştirme sırasında kodu bağlamak, her seferinde yeniden derlemekten hızlıdır.
- Disk şişti: docker system prune ile kullanılmayan imaj ve ağları temizleyin.
© 2026 Yazılım Atölyesi