Makale Başlıkları
- Docker Compose Ne İşe Yarar?
- compose.yaml Dosyasının Temel Yapısı
- Temel Compose Komutları
- Ortam Değişkenleri ve .env Dosyası
- Servis Sırası Yetmez: Healthcheck ile Hazır Olmayı Bekleyin
- Profiller: Aynı Dosyada Birden Çok Senaryo
- Compose Watch ile Canlı Geliştirme
- Gerçek Bir Örnek: WordPress + MySQL
- Birden Fazla Compose Dosyası ve Ortam Ayrımı
- Compose ile Ölçekleme
- Dikkat Edilmesi Gerekenler
- Compose’u Nerede Çalıştırmalı?
- Sıkça Sorulan Sorular
Kisaca
Docker Compose, birbirine bagli birden cok konteyneri (web, veritabani, onbellek gibi) tek bir compose.yaml dosyasinda tanimlayip tek komutla ayaga kaldiran bir aractir. Bu rehber dosya yapisini, temel komutlari, .env ve secrets kullanimini, healthcheck’i ve calisan ornekleri adim adim gosterir.
- Cekirdek yapi: services zorunlu; volumes ve networks ust seviyede tanimlanir, servisler birbirine servis adiyla erisir.
- Gunluk komutlar: docker compose up -d, ps, logs -f, down; V1’in tireli docker-compose yerine artik bosluklu docker compose (V2) kullanilir.
- depends_on tek basina yalnizca baslatma sirasini garanti eder; veritabani “hazir” olana kadar beklemek icin healthcheck + condition: service_healthy gerekir.
- Parolalari compose dosyasina gommeyin: .env veya secrets kullanin, .gitignore ve .dockerignore’a ekleyin; imajlarda sabit surum etiketi tercih edin.
- profiles, compose watch, –scale ve coklu dosya ile gelistirme/uretim ayrimi; kalici WordPress + MySQL ornegi dahil.
Docker Compose, birden çok konteynerden oluşan uygulamaları tek bir YAML dosyasıyla tanımlayıp yöneten bir araçtır. Tek bir docker run komutuyla bir konteyner çalıştırmak kolaydır; ancak gerçek uygulamalar genellikle bir web sunucusu, bir veritabanı ve belki bir önbellek gibi birbirine bağlı birkaç servisten oluşur. Compose, bu servislerin tamamını, ağlarını ve veri alanlarını (volume) tek bir dosyada tarif eder ve hepsini tek komutla ayağa kaldırır. Bu rehberde Docker Compose’un mantığını, dosya yapısını ve günlük kullanımda gerçekten işinize yarayacak komutları, ürettiğimiz çalışan örneklerle birlikte adım adım anlatıyoruz.
Compose ile çok servisli projelerinizi düzenli biçimde çalıştırmak için kendi VPS/sunucunuza Docker kurmanız yeterlidir.
Docker Compose Ne İşe Yarar?
Compose’un temel amacı, çok konteynerli bir uygulamanın tüm yapısını kod olarak (Infrastructure as Code) tanımlamaktır. Bir compose.yaml dosyasında hangi servislerin çalışacağını, hangi imajları kullanacaklarını, hangi portları açacaklarını ve birbirleriyle nasıl konuşacaklarını yazarsınız. Böylece projeyi başka bir sunucuya taşımak, ekip arkadaşlarınızla paylaşmak veya sıfırdan yeniden kurmak tek komuta iner. Aynı dosya, dizüstü bilgisayarınızda ve canlı sunucunuzda neredeyse birebir aynı sonucu üretir; “bende çalışıyordu” tartışmalarını büyük ölçüde bitirir.
Compose’u öne çıkaran bir diğer nokta, formatın artık Docker’a özel olmaktan çıkıp açık bir standart (Compose Specification) hâline gelmesidir. Bu sayede aynı compose.yaml dosyasını Docker dışında Podman gibi başka çalışma zamanlarıyla da kullanabilirsiniz. Standartla birlikte eski version: "3.8" satırına da artık ihtiyaç kalmadı; dosyanızın en üstüne doğrudan services yazarak başlayabilirsiniz.
compose.yaml Dosyasının Temel Yapısı
Compose dosyasının ana bölümü services‘tir; her servis bir konteynere karşılık gelir. İsteğe bağlı olarak üst seviyede volumes ve networks tanımlanır. Bir web sunucusu ve bir veritabanından oluşan basit bir örnek:
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: postgres:18
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: gizli_parola
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Burada web servisi 8080 portunu host’a açar, db servisi ise verisini kalıcı bir volume’de saklar. depends_on, db’nin web’den önce başlatılmasını sağlar. Servislerin birbirini bulması için ekstra bir şey yapmanıza gerek yok: Compose her proje için otomatik bir ağ oluşturur ve servisler birbirine servis adıyla erişir. Yani web konteyneri veritabanına db:5432 adresinden bağlanır; IP adresi ezberlemenize gerek kalmaz.
En sık kullanılan servis alanları
| Alan | Ne işe yarar |
|---|---|
image |
Hazır bir imajı (örn. nginx:latest) kullanır. |
build |
Kendi Dockerfile’ınızdan imaj derler. |
ports |
Host portunu konteyner portuna eşler ("8080:80"). |
volumes |
Kalıcı veri veya host dizinini konteynere bağlar. |
environment / env_file |
Ortam değişkenlerini doğrudan veya dosyadan verir. |
depends_on |
Başlatma sırasını (ve koşulunu) belirler. |
restart |
Çökme/yeniden başlatma davranışını ayarlar (unless-stopped önerilir). |
healthcheck |
Servisin “hazır” olup olmadığını periyodik kontrol eder. |
Temel Compose Komutları
Tüm yığını yönetmek birkaç komuta indirgenir:
docker compose up # servisleri olusturur ve baslatir (log akisiyla) docker compose up -d # arka planda (detached) baslatir docker compose up -d --build # imajlari yeniden derleyip baslatir docker compose ps # calisan servisleri listeler docker compose logs -f # loglari canli izler docker compose exec web sh # calisan bir konteynerde komut calistirir docker compose stop # silmeden durdurur docker compose down # konteyner ve aglari durdurur + siler docker compose down -v # ek olarak volume'lari da siler (VERI GIDER)
Dikkat: komut artık tireli eski docker-compose değil, boşluklu docker compose biçimindedir (Compose V2). Eski V1 aracı 2024’te kullanımdan kaldırıldı; güncel Docker kurulumlarında Compose, Docker CLI’nın bir eklentisi olarak gelir. Sürümünüzü docker compose version ile doğrulayabilirsiniz.
Ortam Değişkenleri ve .env Dosyası
Parolaları, port numaralarını ve imaj etiketlerini doğrudan compose.yaml içine gömmek yerine bir .env dosyasına almak hem daha temiz hem de daha güvenlidir. Compose, dosyayla aynı dizindeki .env dosyasını otomatik okur ve ${DEGISKEN} söz dizimiyle değerleri yerine koyar:
# .env
POSTGRES_PASSWORD=cok_gizli
WEB_PORT=8080
# compose.yaml icinde
services:
web:
image: nginx:latest
ports:
- "${WEB_PORT}:80"
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Önemli bir kural: .env dosyanızı asla sürüm kontrolüne (Git) eklemeyin. .gitignore ve .dockerignore dosyalarına ekleyerek hem gizli değerlerin paylaşılmasını hem de imaj katmanlarına sızmasını önleyin. Gerçekten hassas veriler (veritabanı parolası, API anahtarı) için ise en temiz yöntem secrets kullanmaktır; bu yöntemde değer ortam değişkeni olarak değil, konteyner içinde /run/secrets/<ad> yolunda bir dosya olarak görünür ve ortam değişkeni dökümlerinde görünmez.
Servis Sırası Yetmez: Healthcheck ile Hazır Olmayı Bekleyin
Compose ile çalışırken en sık yapılan hatalardan biri, depends_on‘un veritabanının “hazır” olmasını beklediğini sanmaktır. Oysa varsayılan hâliyle depends_on yalnızca konteynerin başlamasını bekler; içindeki PostgreSQL henüz bağlantı kabul etmiyor olsa bile web servisi ayağa kalkar ve “connection refused” hatası alırsınız. Doğru çözüm, bağımlılığa bir healthcheck tanımlayıp depends_on içinde condition: service_healthy koşulunu kullanmaktır:
services:
web:
image: nginx:latest
depends_on:
db:
condition: service_healthy
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
Bu kurulumda web servisi, veritabanı gerçekten sağlık kontrolünü geçene kadar başlamaz. start_period alanı, servisin ilk açılışında biraz tolerans tanır; başlangıçtaki başarısız denemeleri “sağlıksız” saymaz. Bu küçük ayar, özellikle veritabanı, RabbitMQ veya Elasticsearch gibi açılışı yavaş servislerle çalışırken sayısız hatadan kurtarır.
Profiller: Aynı Dosyada Birden Çok Senaryo
Bazı servisleri yalnızca belirli durumlarda çalıştırmak isteyebilirsiniz; örneğin bir veritabanı yönetim paneli yalnızca geliştirme sırasında lazımdır. profiles alanı tam da bunun içindir. Bir servise profil atadığınızda, o servis yalnızca ilgili profil etkinleştirildiğinde başlar:
services:
app:
image: myapp:latest
adminer:
image: adminer
ports:
- "8081:8080"
profiles: ["dev"]
# Sadece app calisir:
# docker compose up -d
# Yonetim paneli de dahil:
# docker compose --profile dev up -d
Böylece tek bir compose.yaml ile hem yalın üretim çalıştırması hem de zenginleştirilmiş geliştirme ortamı kurabilirsiniz. Üretimde gereksiz servisleri çalıştırarak kaynak harcamazsınız.
Compose Watch ile Canlı Geliştirme
Geliştirme sırasında kodu her değiştirdiğinizde konteyneri elle yeniden derlemek zaman kaybıdır. Güncel Compose sürümleriyle gelen watch özelliği, host’taki dosya değişikliklerini izleyip konteyneri otomatik günceller. Üç temel eylem vardır: sync (dosyaları kopyalar, hot-reload destekleyen çerçeveler için ideal), rebuild (bağımlılık değişince imajı yeniden derler) ve sync+restart (yapılandırma dosyaları için kopyalayıp servisi yeniden başlatır).
services:
app:
build: .
develop:
watch:
- action: sync
path: ./src
target: /app/src
ignore:
- node_modules/
- action: rebuild
path: package.json
Ardından docker compose watch komutunu çalıştırırsınız; ./src altındaki bir dosyayı kaydettiğinizde değişiklik anında konteynere yansır, package.json değişirse imaj yeniden derlenir. Performans için node_modules, .git gibi büyük dizinleri mutlaka ignore ile dışlayın.
Gerçek Bir Örnek: WordPress + MySQL
Yukarıdaki parçaları birleştirelim. Aşağıdaki dosya, kalıcı veritabanı, sağlık kontrolü ve .env kullanan, çalışmaya hazır bir WordPress kurulumudur:
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: mysql:8.4
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
wp_data:
db_data:
docker compose up -d dedikten sonra tarayıcıdan http://sunucu-ip:8080 adresine girdiğinizde WordPress kurulum sihirbazı sizi karşılar. restart: unless-stopped sayesinde sunucu yeniden başlasa bile servisler kendiliğinden ayağa kalkar.
Birden Fazla Compose Dosyası ve Ortam Ayrımı
Geliştirme ve üretim ortamlarını ayırmanın temiz bir yolu, ortak ayarları compose.yaml içinde tutup ortama özel farkları ayrı bir dosyaya almaktır. Compose, compose.override.yaml dosyasını varsayılan olarak okur; üretim için ayrı bir dosyayı ise elle belirtirsiniz:
docker compose -f compose.yaml -f compose.prod.yaml up -d
İkinci dosyadaki değerler ilkinin üzerine yazılır. Aynı servisin geliştirme makinesinde kaynak kodu mount edip üretimde imajdan çalışmasını bu yöntemle kolayca sağlayabilirsiniz.
Compose ile Ölçekleme
Aynı servisten birden fazla kopya çalıştırmak (örneğin yük altındaki bir uygulama sunucusu) için --scale bayrağı yeterlidir:
docker compose up -d --scale app=3
Bu komut app servisinden üç kopya başlatır. Yalnız dikkat: ölçeklediğiniz serviste sabit bir host portu (ports) tanımlamamalısınız, aksi halde port çakışır. Önüne bir ters vekil (reverse proxy) koyup trafiği kopyalara dağıtmak en yaygın çözümdür. Tek sunucuda Compose ölçeklemesi pratik bir sınıra kadar gider; çok sunuculu, kendi kendini iyileştiren bir kümeye ihtiyacınız varsa Kubernetes devreye girer.
Dikkat Edilmesi Gerekenler
serviceszorunlu üst seviye anahtardır; servis içinde referans verilenvolumesvenetworksayrıca üst seviyede tanımlanmalıdır.depends_ontek başına yalnızca başlatma sırasını garanti eder, servisin “hazır” olmasını değil; veritabanı hazırlığı için healthcheck +condition: service_healthykullanın.docker compose down -vnamed volume’ları siler; veritabanı verinizi kaybetmemek için bu komutu dikkatli kullanın. Yalnızca konteynerleri yenilemek istiyorsanız-vbayrağını kullanmayın.- Üretimde parolaları doğrudan dosyaya yazmak yerine
.envdosyası veya secret yönetimi tercih edin; her ikisini de.gitignoreve.dockerignoreiçine ekleyin. - İmajlarda
latestyerine sabit sürüm etiketi (örn.postgres:18) kullanmak, beklenmedik güncellemelerin üretimi bozmasını engeller. - Konteyner günlüklerinin diski doldurmaması için log sürücüsüne boyut sınırı koymayı ihmal etmeyin.
Compose’u Nerede Çalıştırmalı?
Docker Compose, paylaşımlı hosting yerine kök (root) erişiminizin olduğu bir ortamda çalışır; çünkü Docker’ı kurmak ve servisleri yönetmek için tam yetki gerekir. Çok servisli bir Compose yığınını sorunsuz çalıştırmak için ayrılmış kaynaklara, hızlı NVMe diske ve düşük gecikmeli bir ağa ihtiyacınız vardır. Alastyr, İzmir’deki kendi veri merkezinde (kiralık değil, N+1 yedekli klima/jeneratör/UPS ile Tier III standartlarında) barındırdığı KVM tabanlı VPS ve bulut sunucu çözümleriyle bu ihtiyacı karşılar. Türkiye lokasyonu sayesinde yerel kullanıcılarınıza düşük gecikmeyle hizmet verir; tüm altyapı 2002’den beri %100 Türk sermayesiyle yönetilir, 7/24 destek ekibi ofiste her zaman hazırdır.
Sıkça Sorulan Sorular
docker-compose ile docker compose farkı ne?
Eski tireli sürüm (V1) ayrı bir Python aracıydı ve 2024’te kullanımdan kaldırıldı. Güncel sürüm (V2) doğrudan Docker CLI’ya entegredir ve boşluklu docker compose biçiminde çalışır. Yeni projelerde her zaman V2 söz dizimini kullanın.
compose.yaml dosyasının başına version yazmam gerekir mi?
Hayır. Compose Specification ile birlikte version alanı gereksiz hâle geldi; dosyaya doğrudan services ile başlayabilirsiniz. Eski örneklerde gördüğünüz version: "3.8" satırı artık dikkate alınmaz.
depends_on neden veritabanını beklemiyor?
Çünkü tek başına depends_on yalnızca konteynerin başlamasını bekler, içindeki servisin bağlantı kabul etmeye hazır olmasını değil. Bağımlılığa bir healthcheck ekleyip depends_on içinde condition: service_healthy kullanırsanız, bağımlı servis gerçekten hazır olana kadar bekler.
Compose üretim için uygun mu?
Tek sunuculu küçük-orta ölçekli üretim için gayet uygundur; profiller, healthcheck, secrets ve restart politikalarıyla sağlam kurulumlar yapabilirsiniz. Çok sunuculu, otomatik ölçeklenen ve kendini iyileştiren ortamlar için Kubernetes daha uygundur.
Verilerim kalıcı mı?
Yalnızca volume tanımladığınız servislerde. Volume olmadan konteyner silindiğinde içindeki veri de kaybolur. Veritabanı gibi kalıcılık isteyen servislerde mutlaka named volume kullanın ve docker compose down -v komutunu dikkatli çalıştırın.
Parolaları compose dosyasına yazmak güvenli mi?
Önerilmez. Parolaları .env dosyasına alın ve bu dosyayı .gitignore ile sürüm kontrolünün dışında tutun. Daha hassas değerler için Compose’un secrets mekanizmasını kullanın; bu yöntemde değer konteyner içinde dosya olarak mount edilir ve ortam değişkenlerinde görünmez.
Compose Watch ne işe yarar?
Geliştirme sırasında host’taki dosya değişikliklerini izleyip konteyneri otomatik günceller. sync dosyaları kopyalar, rebuild bağımlılık değişiminde imajı yeniden derler, sync+restart ise yapılandırma değişiminde servisi yeniden başlatır. docker compose watch ile başlatılır.
Aynı servisten birden fazla kopya çalıştırabilir miyim?
Evet, docker compose up -d --scale app=3 komutuyla. Yalnız ölçeklediğiniz serviste sabit host portu tanımlamayın; trafiği kopyalara dağıtmak için önüne bir ters vekil (reverse proxy) koyun.
Compose nasıl güncellenir?
Docker güncel olduğunda Compose V2 dahil gelir; ayrı bir kurulum gerekmez. Sürümünüzü docker compose version ile kontrol edebilir, Docker Engine’i güncelleyerek Compose’u da güncel tutabilirsiniz.
Docker Projeleriniz İçin Sunucu
Çok servisli Compose uygulamalarınız için NVMe SSD’li, ayrılmış kaynaklı, İzmir veri merkezinde barındırılan VPS ve bulut sunucu çözümleri.





