Modern yazılım geliştirme dünyasında mikroservis mimarisi, büyük ve karmaşık uygulamaları daha küçük, bağımsız ve yönetilebilir servislere ayırmak için kullanılan bir mimari yaklaşımdır. Bu yapı, ekiplerin farklı servisler üzerinde bağımsız çalışmasına, servislerin ihtiyaçlarına göre ayrı ayrı ölçeklendirilmesine ve birbirlerinden bağımsız şekilde güncellenebilmesine olanak tanır.
Docker Compose Nedir?
Docker Compose, birden fazla Docker container'ını tek bir uygulama yapısı altında tanımlamak ve yönetmek için kullanılan bir araçtır. YAML tabanlı bir yapılandırma dosyası üzerinden servisleri, ağları, volume'leri, environment variable'ları ve diğer container ayarlarını tanımlamanıza olanak tanır.
Özellikle geliştirme, test ve küçük ölçekli deployment ortamlarında birden fazla servisten oluşan uygulamaları tek bir komutla başlatmak, durdurmak ve yönetmek için oldukça kullanışlıdır.
Docker Compose'u Kubernetes gibi kapsamlı bir container orkestrasyon platformuyla karıştırmamak gerekir. Compose daha çok çoklu container uygulamalarının tanımlanması ve yönetilmesine odaklanırken, Kubernetes büyük ölçekli ve dağıtık container ortamları için daha kapsamlı orkestrasyon yetenekleri sunar.
Kurulum
Modern Docker kurulumlarında Docker Compose, docker compose komutunu sağlayan Compose Plugin olarak kullanılabilir. Ubuntu ve Debian tabanlı sistemlerde Docker'ın resmi paketleri kullanılıyorsa aşağıdaki bileşenler kurulabilir:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginKurulumun başarılı olduğunu kontrol etmek için:
docker compose versionNot: Docker Engine ve Docker Compose Plugin'in dağıtımın kendi depolarından veya Docker'ın resmi depolarından kurulması mümkündür. Paket isimleri ve sürümleri kullanılan Linux dağıtımına göre değişebilir.
Temel Docker Compose Yapılandırması
Aşağıdaki örnekte bir web uygulaması, PostgreSQL veritabanı ve Redis servisi birlikte tanımlanmaktadır. Güncel Compose Specification kullanıldığında version alanına ihtiyaç yoktur.
services:
web:
build: ./web
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://appuser:strong-password@postgres:5432/appdb
REDIS_URL: redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: strong-password
POSTGRES_DB: appdb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:Compose tarafından oluşturulan varsayılan ağ sayesinde servisler birbirlerine servis adları üzerinden erişebilir. Örneğin web container'ı PostgreSQL'e postgres:5432, Redis'e ise redis:6379 adresleri üzerinden bağlanabilir.
ports ile yalnızca host üzerinden erişilmesi gereken servislerin portları dışarı açılmalıdır. PostgreSQL ve Redis gibi backend servislerinin portlarını gereksiz yere host'a yayınlamak yerine Compose ağı içerisinde erişilebilir bırakmak daha güvenli bir yaklaşımdır.
Servisleri Yönetme
Compose dosyasının bulunduğu dizinde tüm servisleri arka planda başlatmak için:
docker compose up -dÇalışan container'ları görüntülemek için:
docker compose psServis loglarını takip etmek için:
docker compose logs -fBelirli bir servisin loglarını görmek için:
docker compose logs -f webUygulama stack'ini durdurmak için:
docker compose downVolume'lerin de silinmesi isteniyorsa -v seçeneği kullanılabilir. Ancak bu işlem PostgreSQL gibi stateful servislerin verilerini silebileceğinden dikkatli kullanılmalıdır:
docker compose down -vHealthcheck Kullanımı
Bir container'ın çalışıyor olması, uygulamanın gerçekten kullanılabilir olduğu anlamına gelmez. Örneğin PostgreSQL container'ı çalışıyor olabilir ancak veritabanı henüz bağlantı kabul etmeye hazır olmayabilir.
Bu nedenle kritik servislerde healthcheck tanımlamak ve servis bağımlılıklarını gerektiğinde bu healthcheck sonuçlarına göre yönetmek faydalıdır.
healthcheck:
test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
interval: 10s
timeout: 5s
retries: 5Burada önemli bir ayrım vardır: Docker Compose'taki depends_on, tek başına uygulamanın sağlıklı olduğunu garanti etmez. condition: service_healthy kullanıldığında Compose, bağımlı servisi başlatmadan önce ilgili healthcheck'in başarılı olmasını bekleyebilir.
Resource Limitleri
Container'ların sınırsız kaynak tüketmesini engellemek için CPU ve bellek kullanımının kontrol edilmesi önemlidir. Kullanılacak kaynak ayarları Compose sürümüne ve deployment ortamına göre değişebileceğinden, üretim ortamında kullanılan Compose implementasyonunun desteklediği alanlar kontrol edilmelidir.
Örneğin bazı Compose ortamlarında servis için CPU ve bellek limitleri tanımlanabilir:
services:
web:
image: my-web-app:latest
deploy:
resources:
limits:
cpus: "1.0"
memory: 512Mdeploy bölümündeki bazı özelliklerin davranışı kullanılan çalışma ortamına göre değişebilir. Bu nedenle Docker Compose ile Docker Swarm veya Kubernetes yapılandırmalarının aynı şekilde çalışacağı varsayılmamalıdır.
Environment Variable ve Secret Yönetimi
Parola, API anahtarı ve veritabanı bilgileri gibi hassas verilerin Compose dosyasına doğrudan yazılması önerilmez. Geliştirme ortamlarında .env dosyası kullanılabilir ancak bu dosyanın kaynak kod deposuna yanlışlıkla eklenmemesine dikkat edilmelidir.
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}Örneğin .env dosyası:
POSTGRES_USER=appuser
POSTGRES_PASSWORD=guclu-ve-gizli-parola
POSTGRES_DB=appdbÜretim ortamlarında hassas bilgilerin yönetimi için kullanılan deployment platformunun secret management özelliklerinden yararlanmak daha güvenli bir yaklaşımdır.
Docker Compose ile Ağ Yönetimi
Compose, varsayılan olarak aynı Compose projesindeki servisler için bir ağ oluşturur. Servisler bu ağ üzerinde birbirlerine servis isimleri üzerinden ulaşabilir.
services:
web:
build: ./web
networks:
- backend
postgres:
image: postgres:15-alpine
networks:
- backend
networks:
backend:Bu örnekte web servisi PostgreSQL'e postgres hostname'i üzerinden erişebilir. PostgreSQL portunun host'a açılması gerekmez.
Volume ve Veri Kalıcılığı
Container'lar geçici çalışma ortamlarıdır. Container silindiğinde container'ın kendi dosya sistemindeki veriler de kaybolabilir. PostgreSQL gibi stateful servislerde verilerin kalıcı olması için Docker volume kullanılmalıdır.
services:
postgres:
image: postgres:15-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Volume kullanılması tek başına yedekleme anlamına gelmez. Üretim ortamlarında veritabanı için ayrıca düzenli backup, restore testi ve uygun bir disaster recovery planı oluşturulmalıdır.
Log Yönetimi
Birden fazla servisten oluşan uygulamalarda logların merkezi şekilde toplanması hata ayıklama ve gözlemlenebilirlik açısından önemlidir.
Geliştirme ortamlarında Compose logları doğrudan takip edilebilir:
docker compose logs -fÜretim ortamlarında ise uygulamanın gereksinimlerine göre merkezi loglama çözümleri, log driver'ları veya harici gözlemlenebilirlik platformları kullanılabilir.
En İyi Uygulamalar
Her servis için uygun healthcheck tanımlayın.
Container'ların CPU ve bellek tüketimini kontrol altında tutun.
Parola ve API anahtarı gibi hassas bilgileri Compose dosyasına doğrudan yazmayın.
Backend servislerinin portlarını gereksiz yere host'a açmayın.
Stateful servisler için Docker volume kullanın.
Volume kullanmanın yedekleme yerine geçmediğini unutmayın ve düzenli backup alın.
Logları merkezi olarak toplayarak uygulamanın gözlemlenebilirliğini artırın.
Production ortamında kullanılan image sürümlerini kontrollü şekilde yönetin ve mümkün olduğunca doğrulanabilir sürümler kullanın.
Compose dosyasını kaynak kodla birlikte versiyon kontrolünde tutun ancak secret içeren dosyaları repository'ye eklemeyin.
Servisler arasındaki bağımlılıkları
depends_onile açıkça tanımlayın; uygulama seviyesinde de bağlantı hatalarına karşı retry mekanizmaları kullanın.
Sonuç
Docker Compose, birden fazla container'dan oluşan uygulamaları tanımlamak ve yönetmek için pratik ve güçlü bir araçtır. Tek bir YAML dosyası üzerinden servisleri, ağları, volume'leri ve çalışma yapılandırmalarını yönetebilmek özellikle geliştirme, test ve küçük ölçekli deployment süreçlerini önemli ölçüde kolaylaştırır.
Mikroservis mimarisinde Docker Compose kullanırken yalnızca container'ları çalıştırmak yerine healthcheck, kaynak yönetimi, secret yönetimi, ağ izolasyonu, kalıcı veri ve loglama gibi konuların da birlikte ele alınması gerekir. Uygulama büyüdükçe ve orkestrasyon ihtiyaçları arttıkça Kubernetes gibi daha kapsamlı platformlara geçiş değerlendirilebilir.