Docker Compose Nedir, Nasıl Kullanılır?

Docker Compose Nedir, Nasıl Kullanılır?

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.

Mail hosting 1 ay ücretsiz

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

  • services zorunlu üst seviye anahtardır; servis içinde referans verilen volumes ve networks ayrıca üst seviyede tanımlanmalıdır.
  • depends_on tek 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_healthy kullanın.
  • docker compose down -v named volume’ları siler; veritabanı verinizi kaybetmemek için bu komutu dikkatli kullanın. Yalnızca konteynerleri yenilemek istiyorsanız -v bayrağını kullanmayın.
  • Üretimde parolaları doğrudan dosyaya yazmak yerine .env dosyası veya secret yönetimi tercih edin; her ikisini de .gitignore ve .dockerignore içine ekleyin.
  • İmajlarda latest yerine 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.

VPS/Sunucu Çözümleri →

Türkiye'nin En Çok Tavsiye Edilen Domain, Hosting ve Bulut Servis Sağlayıcısı
İnternet sitesi Alastyr İnternet Sitesi
Yazı oluşturuldu 511

Benzer yazılar

Aramak istediğinizi üstte yazmaya başlayın ve aramak için enter tuşuna basın. İptal için ESC tuşuna basın.

Üste dön