Modern uygulama geliştirme süreçlerinde, mikroservis mimarileri ve konteyner teknolojileri hızla benimseniyor. Ancak birden fazla servisten oluşan bir uygulamanın tüm bileşenlerini tek tek yönetmek oldukça karmaşık olabilir. İşte tam bu noktada Docker Compose devreye girerek, çok konteynerli Docker uygulamalarını tanımlama ve çalıştırma sürecini basitleştiriyor. Bu kapsamlı rehberde, Ubuntu üzerinde Docker Compose’u nasıl kuracağınızı, temelden ileri düzeye nasıl kullanacağınızı ve gerçek dünya senaryolarında projelerinizi nasıl yöneteceğinizi adım adım öğreneceksiniz. Hazırsanız, konteyner orkestrasyonunun gücünü keşfetmeye başlayalım!
Docker Compose’u Anlamak: Neden İhtiyacımız Var?
Günümüzün karmaşık yazılım projeleri genellikle tek bir büyük uygulamadan (monolit) ziyade, birbirleriyle iletişim kuran küçük, bağımsız servislerden (mikroservisler) oluşur. Örneğin, bir web uygulaması düşünün: kullanıcı arayüzü (frontend), API sunucusu (backend), veritabanı, önbellek sistemi (cache) ve belki de bir mesaj kuyruğu gibi farklı bileşenlere sahip olabilir. Bu bileşenlerin her biri kendi ortamında çalışır ve genellikle farklı teknolojilerle geliştirilir. Docker, her bir servisi kendi izole konteyneri içinde çalıştırmamızı sağlayarak bu karmaşıklığı büyük ölçüde azaltır. Ancak, bu kadar çok konteyneri aynı anda başlatmak, durdurmak, ağlarını yapılandırmak ve birbirleriyle iletişim kurmalarını sağlamak elle yapıldığında yorucu ve hataya açık bir süreç haline gelebilir.
İşte tam bu noktada Docker Compose, geliştiricilerin hayatını kolaylaştıran güçlü bir araç olarak öne çıkar. Compose, çoklu konteynerli Docker uygulamalarını tanımlamak ve çalıştırmak için bir YAML dosyası kullanır. Bu YAML dosyası, uygulamanızın tüm servislerini, bu servislerin hangi Docker imajlarından oluşturulacağını, hangi portları kullanacaklarını, hangi ağlara dahil olacaklarını, hangi birimlere (volume) sahip olacaklarını ve hatta birbirlerine olan bağımlılıklarını tek bir yerde belirtmenize olanak tanır. Böylece, tek bir komutla (docker-compose up) uygulamanızın tüm bileşenlerini belirlenen konfigürasyonla ayağa kaldırabilir, durdurabilir veya yeniden başlatabilirsiniz. Bu, özellikle geliştirme ortamlarında tutarlılığı sağlamak, yeni bir geliştiriciyi projeye dahil etmek veya bir entegrasyon test ortamı kurmak için paha biçilmez bir kolaylık sunar. Compose, her bir servisin yaşam döngüsünü bağımsız olarak yönetme esnekliği sunarken, aynı zamanda tüm uygulamanın bir bütün olarak ele alınmasını sağlar. Konteynerleşme dünyasında, uygulamanızın “nasıl” çalıştığını değil, “ne” çalıştığını tanımlamanıza olanak tanıyan bir deklaratif yaklaşım sunar.
Özetle, Docker Compose’un temel amacı, birden fazla Docker konteynerini içeren uygulamaları daha kolay yönetilebilir, taşınabilir ve tekrarlanabilir hale getirmektir. Geliştirme, test ve hatta küçük ölçekli üretim ortamlarında dahi büyük avantajlar sağlar. Bu sayede, geliştiriciler altyapı detaylarıyla boğuşmak yerine, uygulamanın asıl işlevselliğine odaklanabilirler. Compose, Docker ekosisteminin ayrılmaz bir parçasıdır ve modern uygulama geliştirme pratiklerinde vazgeçilmez bir araç haline gelmiştir. Şimdi, bu güçlü aracı Ubuntu sistemimize nasıl kuracağımıza ve kullanacağımıza geçelim.
docker-compose.yml dosyasını kullanarak uygulamanın tüm bağımlılıklarını aynı konfigürasyonla çalıştırabilir, bu da tutarlılığı ve işbirliğini artırır.
Ubuntu’da Docker ve Docker Compose Kurulumu: Adım Adım Rehber
Docker Compose kullanmaya başlamadan önce, sisteminizde Docker Engine’in kurulu olması gerekmektedir. Bu bölümde, Ubuntu işletim sisteminde hem Docker’ı hem de Docker Compose’u nasıl kuracağınızı adım adım anlatacağız. Kurulum süreci oldukça basittir, ancak her adımın doğru şekilde takip edilmesi önemlidir.
Docker Engine Kurulumu Nasıl Yapılır?
Docker’ı kurmanın en güvenli ve önerilen yolu, resmi Docker deposunu kullanmaktır. Bu sayede her zaman en güncel ve kararlı sürüme sahip olursunuz. Aşağıdaki adımları izleyerek Docker Engine’i kurabilirsiniz:
- Mevcut Docker Sürümlerini Kaldırma (İsteğe Bağlı): Eğer daha önce Docker’ın eski bir sürümünü kurduysanız, çakışmaları önlemek için önce onu kaldırmalısınız.
- Gerekli Paketleri Yükleme: Docker deposunu kullanmak için bazı önkoşul paketlere ihtiyacımız var.
- Docker’ın Resmi GPG Anahtarını Ekleme: Güvenliği sağlamak için Docker’ın resmi GPG anahtarını eklememiz gerekiyor. Bu, indirdiğimiz paketlerin Docker tarafından imzalandığını doğrulamamızı sağlar.
- Docker Deposunu Ekleme: Şimdi Docker’ın kararlı deposunu APT kaynaklarımıza ekleyebiliriz.
- Docker Engine’i Yükleme: Depo eklendikten sonra, Docker Engine’i yükleyebiliriz.
- Docker’ı Test Etme: Kurulumun başarılı olup olmadığını test etmek için bir “hello-world” konteynerini çalıştırabilirsiniz.
- Docker Komutlarını Sudo Olmadan Çalıştırma (Önerilen): Her Docker komutunu
sudoile çalıştırmak zahmetli olabilir. Kullanıcınızıdockergrubuna ekleyerek bu kısıtlamayı kaldırabilirsiniz. - Docker Compose’u İndirme: GitHub’daki Docker Compose deposundan en son kararlı sürümü indirin.
- Çalıştırılabilir İzinleri Verme: İndirdiğiniz dosyaya çalıştırma izni vermeniz gerekir.
- Kurulumu Doğrulama: Kurulumun başarılı olup olmadığını kontrol edin.
web/Dockerfile: Flask uygulamasını çalıştıracak Docker imajını tanımlar.web/requirements.txt: Flask uygulamasının Python bağımlılıklarını içerir.web/app.py: Basit bir Flask uygulaması. Redis’e bağlanmaya ve bir sayaç tutmaya çalışır.version: '3.8': Compose dosya formatının sürümünü belirtir. En son sürüm genellikle en iyi özellikleri sunar.services: Uygulamamızın tüm servislerini içerir.webservisi:build: ./web:webdizinindekiDockerfile‘ı kullanarak bir Docker imajı oluşturur.ports: "5000:5000": Ana makinenin (host) 5000 portunu,webkonteynerinin 5000 portuna eşler. Böylece tarayıcınızdan uygulamaya erişebilirsiniz.volumes: ./web:/app: Yerel./webdizinini konteyner içindeki/appdizinine bağlar. Bu, kodunuzda değişiklik yaptığınızda konteyneri yeniden oluşturmaya gerek kalmadan değişikliklerin anında yansımasını sağlar (geliştirme için idealdir).depends_on: - redis:webservisinin başlamadan önceredisservisinin başlatılmasını beklediğini belirtir.
redisservisi:image: "redis:latest": Docker Hub’dan resmiredis:latestimajını kullanır.ports: "6379:6379": Redis’e ana makineden erişmek isterseniz bu portu açar.volumes: redis_data:/data: Redis verilerini kalıcı olarak depolamak içinredis_dataadında bir Docker Volume kullanır. Bu, konteyner silinse bile verilerin kaybolmamasını sağlar.
volumes: Özel olarak tanımlanmış Docker Volume’larını listeler. Buradaredis_data‘yı tanımlıyoruz.docker compose up:docker-compose.ymldosyasını okur, gerekli imajları indirir/oluşturur ve servisleri başlatır.-d(detach modu): Konteynerleri arka planda çalıştırır, böylece terminaliniz serbest kalır.- Named Volumes (Adlandırılmış Volume’lar): Docker tarafından yönetilen özel bir alanda depolanır. Konteynerler silinse bile volume’lar kalır. Önceki Redis örneğinde
redis_dataadında bir volume kullandık. - Bind Mounts (Bağlama Noktaları): Ana makine dosya sistemindeki belirli bir dizini doğrudan konteyner içine bağlar. Geliştirme sırasında kod değişikliklerinin anında yansıması için idealdir. (Önceki Flask örneğinde
./web:/appbind mount kullandık.) - Frontend (Web Sunucusu): Bir React uygulamasından oluşur ve Nginx tarafından statik dosyalar olarak sunulur. Kullanıcıların etkileşimde bulunduğu arayüzdür.
- Backend (API Sunucusu): Node.js ile yazılmış bir RESTful API’dir. Veritabanı ile iletişim kurar ve frontend’den gelen istekleri işler.
- Veritabanı: PostgreSQL, uygulamanın tüm verilerini kalıcı olarak depolar.
frontendservisi:build: ./frontend: React uygulamasının statik dosyalarını oluşturan ve Nginx ile sunan birDockerfile‘dan imaj oluşturur.ports: "80:80": Uygulamaya varsayılan HTTP portu üzerinden erişilmesini sağlar.volumes: ./frontend/nginx.conf:/etc/nginx/conf.d/default.conf:ro: Nginx’in özel konfigürasyon dosyasını konteyner içine salt okunur (ro) olarak bağlar.
backendservisi:build: ./backend: Node.js API’sini içeren birDockerfile‘dan imaj oluşturur.environment: Veritabanı bağlantı bilgilerini ortam değişkenleri olarak ayarlar. Buradadbhostname’i, Compose tarafından otomatik olarak oluşturulan ağdaki veritabanı servisinin adıdır.depends_on: db: { condition: service_healthy }: Backend’in sadece veritabanı servisi tamamen sağlıklı olduğunda başlamasını garanti eder. Bu, bağlantı hatalarını önler.volumes: ./backend:/app: Geliştirme kolaylığı için backend kodunu bağlar./app/node_modulesistisnası, host’takinode_modules‘in konteynerdeki ile çakışmasını engeller.
dbservisi:image: postgres:13-alpine: Hafif bir PostgreSQL imajı kullanır.environment: PostgreSQL için gerekli ortam değişkenlerini (veritabanı adı, kullanıcı, şifre) ayarlar.volumes: db_data:/var/lib/postgresql/data: Veritabanı verilerinin kalıcılığını sağlamak için adlandırılmış bir Docker Volume kullanır. Bu, konteyner silinse bile verilerin güvende kalmasını sağlar.healthcheck: Veritabanının bağlantıları kabul etmeye hazır olup olmadığını kontrol eder.
networks: Tüm servisleri aynı özelapp_networkağına dahil eder, böylece birbirleriyle kolayca iletişim kurabilirler.volumes:db_dataadında bir volume tanımlarız.--build: Gerekirse imajları yeniden oluşturur (örneğin,Dockerfileveya uygulama kodunda değişiklik yaptıysanız).
sudo apt-get remove docker docker-engine docker.io containerd runc
Bu komut, sisteminizdeki eski Docker paketlerini kaldıracaktır.
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
Bu komutlar, sisteminizin paket listesini günceller ve gerekli yardımcı programları yükler.
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Bu komut, sisteminize Docker’ın resmi deposunu ekleyecektir. $(lsb_release -cs) kısmı, Ubuntu sürümünüzün kod adını otomatik olarak algılar (örneğin, jammy veya focal).
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Bu komut, Docker Engine’in en son kararlı sürümünü, CLI aracını, containerd ve diğer gerekli eklentileri yükleyecektir.
sudo docker run hello-world
Eğer “Hello from Docker!” mesajını görürseniz, Docker başarıyla kurulmuş demektir.
sudo usermod -aG docker $USER
newgrp docker
newgrp docker komutu, mevcut oturumunuz için grup değişikliklerini uygular. Tamamen etkili olması için oturumu kapatıp açmanız veya sistemi yeniden başlatmanız gerekebilir.
Docker Compose Kurulumu Nasıl Yapılır?
Docker Compose artık Docker Engine ile birlikte docker-compose-plugin olarak geliyor. Yukarıdaki kurulum adımlarında zaten bu eklentiyi yüklemiş olmanız gerekiyor. Ancak, eski bağımsız Docker Compose sürümünü (docker-compose) kullanmak isterseniz, aşağıdaki adımları izleyebilirsiniz. Genellikle yeni projeler için docker compose (plugin versiyonu) kullanılması önerilir.
sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
v2.23.3 yerine en son sürümü kontrol etmek için Docker Compose GitHub Releases sayfasını ziyaret edebilirsiniz.
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
Eğer bir sürüm numarası (örneğin, Docker Compose version v2.23.3) görürseniz, Docker Compose başarıyla kurulmuş demektir. Yeni plugin versiyonu için ise komut docker compose version şeklindedir.
docker compose version
Artık hem Docker Engine hem de Docker Compose sisteminizde çalışmaya hazır. Bir sonraki bölümde, ilk Docker Compose projenizi nasıl oluşturacağınızı ve çalıştıracağınızı öğreneceğiz.
İlk Docker Compose Projenizi Oluşturma: Basit Bir Web Uygulaması
Docker ve Docker Compose’u başarıyla kurduğunuza göre, şimdi ilk çok konteynerli uygulamanızı oluşturma zamanı. Bu bölümde, basit bir Python Flask web uygulaması ve bir Redis önbellek sunucusundan oluşan bir projeyi Docker Compose ile nasıl yöneteceğinizi adım adım göstereceğiz. Bu örnek, Compose’un temel işlevselliğini anlamanıza yardımcı olacaktır.
Proje Yapısı ve Dosyaları Nasıl Oluşturulur?
İlk olarak, projemiz için bir dizin oluşturalım ve gerekli dosyaları bu dizine yerleştirelim. Genellikle bir Docker Compose projesi, ana dizininde bir docker-compose.yml dosyası ve her servis için ayrı bir dizin içinde Dockerfile ve uygulama kodunu barındırır.
mkdir my-flask-app
cd my-flask-app
mkdir web
Şimdi web dizininin içine Flask uygulamamız için gerekli dosyaları oluşturalım:
# web/Dockerfile
FROM python:3.9-slim-buster
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
Bu Dockerfile, Python 3.9 tabanlı bir imaj kullanır, çalışma dizinini ayarlar, bağımlılıkları yükler, uygulama kodunu kopyalar ve Flask uygulamasını 5000 portunda başlatır.
# web/requirements.txt
Flask
redis
# web/app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379) # 'redis' hostname'i Compose tarafından sağlanacak
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Merhaba Docker Compose! Bu sayfa {} kez ziyaret edildi.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
Bu Flask uygulaması, her istekte Redis’teki bir sayacı artırır ve güncel değeri gösterir. Redis sunucusuna redis ana bilgisayar adı üzerinden bağlanmaya çalışır, çünkü Compose varsayılan olarak servis adlarını DNS çözünürlüğü için kullanır.
docker-compose.yml Dosyası Nasıl Yapılandırılır?
Şimdi projemizin kök dizininde (my-flask-app) docker-compose.yml dosyasını oluşturalım. Bu dosya, uygulamamızın servislerini tanımlayacak ve birbirleriyle nasıl etkileşim kuracaklarını belirleyecektir.
# docker-compose.yml
version: '3.8' # Docker Compose dosya formatının sürümü
services:
web: # İlk servisimiz: Flask web uygulaması
build: ./web # 'web' dizinindeki Dockerfile'dan imaj oluştur
ports:
- "5000:5000" # Host'un 5000 portunu konteynerin 5000 portuna yönlendir
volumes:
- ./web:/app # Host'taki ./web dizinini konteynerdeki /app dizinine bağla (geliştirme için faydalı)
depends_on: # Bu servisin başlamadan önce hangi servislerin hazır olmasını beklediğini belirtir
- redis
environment:
FLASK_ENV: development
redis: # İkinci servisimiz: Redis önbellek sunucusu
image: "redis:latest" # Docker Hub'dan 'redis:latest' imajını kullan
ports:
- "6379:6379" # Redis'e dışarıdan erişmek isterseniz bu portu açabilirsiniz
volumes:
- redis_data:/data # Redis verilerini kalıcı hale getirmek için bir volume kullan
volumes: # Volume tanımlamaları
redis_data: # Redis için kalıcı veri depolama birimi
driver: local
Bu docker-compose.yml dosyasında:
Uygulamayı Çalıştırma ve Yönetme
Tüm dosyaları oluşturduktan sonra, projemizin kök dizininde (my-flask-app) aşağıdaki komutu çalıştırarak uygulamamızı başlatabiliriz:
docker compose up -d
Komutu çalıştırdıktan sonra, Docker Compose’un imajları oluşturduğunu ve servisleri başlattığını göreceksiniz. Tarayıcınızda http://localhost:5000 adresine giderek Flask uygulamanıza erişebilirsiniz. Sayfayı her yenilediğinizde, Redis’teki sayaç değerinin arttığını göreceksiniz.
Uygulamanın durumunu kontrol etmek için:
docker compose ps
Bu komut, Compose tarafından yönetilen tüm servislerin durumunu gösterir.
Uygulamayı durdurmak ve konteynerleri kaldırmak için:
docker compose down
Bu komut, docker-compose.yml dosyasında tanımlanan ağları ve konteynerleri durdurur ve kaldırır. Eğer -v (--volumes) seçeneğini eklerseniz, tanımlanan volume’ları da kaldırır (bu durumda redis_data volume’u da silinir, dikkatli olun!).
docker compose down -v # Volume'ları da siler
Bu basit örnek, Docker Compose’un çoklu servis uygulamalarını yönetme gücünü göstermektedir. Geliştirme sürecinizi büyük ölçüde hızlandıracak ve kolaylaştıracaktır.
İleri Düzey Docker Compose Kullanımı ve En İyi Uygulamalar
Docker Compose’un temel kullanımını anladıktan sonra, daha karmaşık senaryolarda size yardımcı olacak bazı ileri düzey özelliklere ve en iyi uygulamalara göz atalım. Bu teknikler, Compose dosyalarınızı daha esnek, güvenli ve yönetilebilir hale getirecektir.
Ortam Değişkenleri ve .env Dosyaları Nasıl Kullanılır?
Uygulamalar genellikle veritabanı şifreleri, API anahtarları veya farklı ortamlar için (geliştirme, test, üretim) özel ayarlar gibi hassas bilgilere veya dinamik konfigürasyonlara ihtiyaç duyar. Bu tür bilgileri doğrudan docker-compose.yml dosyasına yazmak güvenlik ve esneklik açısından iyi bir uygulama değildir. Docker Compose, ortam değişkenlerini ve .env dosyalarını kullanarak bu sorunu çözmenizi sağlar.
Projenizin kök dizininde bir .env dosyası oluşturarak ortam değişkenlerini tanımlayabilirsiniz:
# .env
REDIS_PASSWORD=supersecretpassword
DB_HOST=my_database_server
APP_PORT=8080
Daha sonra docker-compose.yml dosyanızda bu değişkenleri referans alabilirsiniz:
# docker-compose.yml
version: '3.8'
services:
web:
build: ./web
ports:
- "${APP_PORT}:5000" # APP_PORT .env dosyasından alınır
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD} # Ortam değişkenini servise aktar
- DB_HOST=${DB_HOST}
redis:
image: "redis:latest"
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"] # Redis şifresini kullan
Compose, docker compose up komutu çalıştığında otomatik olarak .env dosyasını okur ve buradaki değişkenleri YAML dosyasındaki referanslarla değiştirir. Bu yaklaşım, hassas bilgileri versiyon kontrol sisteminden uzak tutmanıza ve farklı ortamlar için kolayca konfigürasyon değiştirmenize olanak tanır.
Volume Yönetimi: Kalıcı Veri Saklama Nasıl Sağlanır?
Konteynerler doğaları gereği geçicidir; bir konteyner silindiğinde içindeki tüm veriler de kaybolur. Veritabanları, log dosyaları veya kullanıcı tarafından yüklenen dosyalar gibi kalıcı olması gereken veriler için Docker Volume’ları kullanılır. İki ana volume türü vardır:
Volume’ları kullanırken, verilerin doğru şekilde yedeklendiğinden ve gerektiğinde kurtarılabildiğinden emin olmak önemlidir.
Ağ Yapılandırması: Özel Ağlar Oluşturma
Docker Compose, varsayılan olarak projeniz için özel bir köprü ağı (bridge network) oluşturur ve tüm servisleri bu ağa dahil eder. Bu sayede servisler birbirleriyle isimleriyle iletişim kurabilirler (örneğin, web servisi redis servisine redis ana bilgisayar adıyla bağlanabilir). Ancak bazen daha karmaşık ağ yapılandırmalarına ihtiyacınız olabilir.
Örneğin, belirli servislerin sadece belirli ağlarda olmasını veya farklı ağlar arasında iletişim kurmasını isteyebilirsiniz:
# docker-compose.yml
version: '3.8'
services:
web:
networks:
- frontend_network
- backend_network
api:
networks:
- backend_network
db:
networks:
- backend_network
networks:
frontend_network:
driver: bridge
backend_network:
driver: bridge
Bu örnekte, web servisi hem frontend_network hem de backend_network‘e bağlıyken, api ve db servisleri sadece backend_network‘e bağlıdır. Bu, ağ segmentasyonu sağlayarak güvenliği artırabilir ve trafik akışını daha iyi kontrol etmenize yardımcı olabilir.
Sağlık Kontrolleri (Healthchecks) Nasıl Yapılır?
Bir servis başlatıldığında, onun hemen kullanıma hazır olduğu anlamına gelmez. Örneğin, bir veritabanı konteyneri ayağa kalkabilir ancak veritabanı sunucusu henüz bağlantıları kabul etmiyor olabilir. Sağlık kontrolleri, Docker’ın bir konteynerin gerçekten “sağlıklı” ve kullanıma hazır olup olmadığını belirlemesini sağlar. Bu, depends_on ile birlikte kullanıldığında daha güvenilir uygulama başlatma süreçleri oluşturur.
# docker-compose.yml
version: '3.8'
services:
web:
build: ./web
ports:
- "5000:5000"
depends_on:
redis:
condition: service_healthy # Redis sağlıklı olana kadar bekle
redis:
image: "redis:latest"
healthcheck:
test: ["CMD", "redis-cli", "ping"] # Redis'in ping komutuna yanıt verip vermediğini kontrol et
interval: 1s # Her 1 saniyede bir kontrol et
timeout: 3s # 3 saniye içinde yanıt gelmezse başarısız say
retries: 5 # 5 başarısız denemeden sonra sağlıksız ilan et
Bu konfigürasyonla, web servisi sadece redis servisi sağlık kontrolünden geçtikten sonra başlayacaktır. Bu, uygulama başlatma sırasında bağlantı hatalarını önlemeye yardımcı olur.
Birden Fazla Compose Dosyası ile Çalışma (-f)
Bazen farklı ortamlar (geliştirme, test, üretim) için Compose dosyalarınızda küçük farklılıklar olabilir. Örneğin, geliştirme ortamında kodunuzu bağlamak için bind mount kullanırken, üretimde daha performanslı named volume’lar kullanmak isteyebilirsiniz. Bu durumda birden fazla Compose dosyası kullanabilirsiniz.
# Geliştirme için:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
# Üretim için (farklı bir veritabanı konfigürasyonu veya daha az loglama ile):
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
Compose, dosyaları belirtilen sıraya göre birleştirir ve daha sonra belirtilen dosyalar önceki dosyalardaki ayarları geçersiz kılar. Bu, temel bir docker-compose.yml dosyasına sahip olup, ortama özel ayarları ayrı dosyalarda tutmanıza olanak tanır.
Bu ileri düzey teknikler, Docker Compose projelerinizi daha güçlü, esnek ve gerçek dünya senaryolarına uygun hale getirmenize yardımcı olacaktır. Konteynerleştirilmiş uygulamalarınızın yönetimini bir üst seviyeye taşıyarak, geliştirme ve dağıtım süreçlerinizde önemli avantajlar sağlayabilirsiniz.
Vaka Analizi: Üç Katmanlı Bir Uygulamanın Docker Compose ile Dağıtımı
Şimdiye kadar öğrendiklerimizi pekiştirmek ve Docker Compose’un gerçek bir senaryoda nasıl kullanılabileceğini göstermek için, yaygın bir üç katmanlı (three-tier) uygulamanın dağıtımını inceleyelim. Bu uygulama, bir ön uç (frontend – React), bir arka uç API’si (backend – Node.js) ve bir veritabanı (PostgreSQL) olmak üzere üç ana bileşenden oluşacak. Amacımız, tüm bu bileşenleri Docker konteynerlerinde çalıştırmak ve Docker Compose ile yönetmektir.
Uygulama Mimarisi ve Bileşenleri
Uygulamamızın bileşenleri ve rolleri şu şekildedir:
Bu üç bileşenin her biri ayrı bir Docker konteynerinde çalışacak ve Docker Compose tarafından yönetilecektir. Bu yaklaşım, her bir bileşenin bağımsız olarak geliştirilmesine, ölçeklenmesine ve güncellenmesine olanak tanır.
docker-compose.yml ile Üç Katmanlı Uygulama Konfigürasyonu
Proje kök dizininde aşağıdaki docker-compose.yml dosyasını oluşturalım. Ayrıca, her servis için ayrı dizinlerde (frontend, backend) gerekli Dockerfile ve uygulama kodlarının bulunduğunu varsayalım.
# docker-compose.yml
version: '3.8'
services:
# Frontend Servisi (Nginx + React)
frontend:
build: ./frontend # frontend dizinindeki Dockerfile'dan imaj oluştur
ports:
- "80:80" # Host'un 80 portunu konteynerin 80 portuna yönlendir
depends_on:
- backend # Frontend'in backend'e bağımlılığı yok ama geliştirme sırasında faydalı olabilir
networks:
- app_network
volumes:
- ./frontend/nginx.conf:/etc/nginx/conf.d/default.conf:ro # Nginx konfigürasyonunu bağla
# Üretim için genellikle sadece build edilmiş statik dosyaları bağlamak yeterlidir
# - ./frontend/build:/usr/share/nginx/html:ro
# Backend Servisi (Node.js API)
backend:
build: ./backend # backend dizinindeki Dockerfile'dan imaj oluştur
ports:
- "3001:3001" # Host'un 3001 portunu konteynerin 3001 portuna yönlendir
environment:
DATABASE_URL: postgres://user:password@db:5432/mydatabase # Veritabanı bağlantı dizesi
NODE_ENV: development
depends_on:
db:
condition: service_healthy # Backend'in db'nin sağlıklı olmasını beklemesi
networks:
- app_network
volumes:
- ./backend:/app # Geliştirme için kod bağlama
- /app/node_modules # node_modules'in host'a yansımamasını sağlar
# Veritabanı Servisi (PostgreSQL)
db:
image: postgres:13-alpine # Hafif bir PostgreSQL imajı
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data # Veritabanı verileri için kalıcı volume
ports:
- "5432:5432" # Sadece geliştirme/debugging için açılabilir, üretimde genellikle kapalıdır
healthcheck: # Veritabanı sağlık kontrolü
test: ["CMD-SHELL", "pg_isready -U user -d mydatabase"]
interval: 5s
timeout: 5s
retries: 5
networks:
- app_network
networks:
app_network:
driver: bridge
volumes:
db_data:
driver: local
Bu docker-compose.yml dosyasındaki önemli noktalar:
Uygulamayı Çalıştırma ve Yönetme
Bu üç katmanlı uygulamayı başlatmak için, docker-compose.yml dosyasının bulunduğu dizinde aşağıdaki komutu çalıştırın:
docker compose up -d --build
Uygulama başarıyla başlatıldıktan sonra, tarayıcınızdan http://localhost adresine giderek frontend’e erişebilirsiniz. Frontend, backend API’sine istekler gönderecek, backend de veritabanı ile etkileşime girecektir.
Servis loglarını takip etmek için:
docker compose logs -f
Belirli bir servisin loglarını görmek için (örneğin backend):
docker compose logs -f backend
Uygulamayı durdurmak ve tüm servisleri kaldırmak için:
docker compose down
Veritabanı verilerini de silmek isterseniz:
docker compose down -v
Bu vaka analizi, Docker Compose’un karmaşık, çok bileşenli uygulamaları tek bir komutla nasıl yönetebileceğini açıkça göstermektedir. Geliştirme ve test süreçlerinizi büyük ölçüde kolaylaştırırken, uygulama bileşenleri arasında tutarlı bir ortam sağlar. Bu, modern DevOps pratiklerinin temel taşlarından biridir.
Sonuç ve Sıkça Sorulan Sorular
Bu kapsamlı rehber boyunca, Ubuntu üzerinde Docker Compose’u kurmaktan, temel bir web uygulamasını çalıştırmaya ve ileri düzey konfigürasyon tekniklerini öğrenmeye kadar birçok konuyu ele aldık. Docker Compose’un, çoklu konteynerli Docker uygulamalarını tanımlama, yapılandırma ve yönetme süreçlerini ne kadar basitleştirdiğini gördük. Geliştirme ortamlarında tutarlılık sağlamak, yeni ekip üyelerini hızlıca projeye dahil etmek ve karmaşık uygulama mimarilerini tek bir YAML dosyasıyla kontrol etmek gibi paha biçilmez avantajlar sunduğunu anladık.
Artık Docker Compose’un gücünü kullanarak kendi çok servisli uygulamalarınızı kolayca yönetebilir, geliştirme süreçlerinizi optimize edebilir ve daha verimli çalışabilirsiniz. Konteynerleşme yolculuğunuzda Docker Compose, vazgeçilmez bir yol arkadaşı olacaktır. Öğrendiğiniz bu bilgilerle, daha karmaşık projelerin üstesinden gelmeye ve modern uygulama dağıtım pratiklerini benimsemeye hazırsınız. Unutmayın, pratik yapmak öğrenmenin anahtarıdır; bu yüzden farklı senaryolarla denemeler yapmaktan çekinmeyin!
Sıkça Sorulan Sorular (SSS)
| Soru | Cevap |
|---|---|
| Docker Compose nedir ve neden kullanmalıyım? | Docker Compose, birden fazla Docker konteynerini içeren uygulamaları tanımlamak ve çalıştırmak için kullanılan bir araçtır. Tek bir YAML dosyası kullanarak uygulamanızın tüm servislerini, ağlarını ve volume’larını yapılandırabilir ve tek bir komutla (docker compose up) tüm uygulamayı başlatabilirsiniz. Karmaşık uygulamaların yönetimini basitleştirir, geliştirme ortamlarında tutarlılık sağlar ve uygulama dağıtımını kolaylaştırır. |
docker-compose ile docker compose arasındaki fark nedir? |
docker-compose, Docker Compose’un orijinal bağımsız Python uygulamasıdır. docker compose ise Docker Engine’in bir parçası olarak gelen yeni ve entegre bir CLI eklentisidir (docker-compose-plugin). Yeni projelerde ve güncel Docker kurulumlarında docker compose kullanılması önerilir, çünkü daha güncel özelliklere sahiptir ve Docker CLI ile daha iyi entegredir. |
docker compose up ile docker compose up -d arasındaki fark nedir? |
docker compose up komutu, servisleri başlatır ve konteynerlerin loglarını doğrudan terminalinizde gösterir. Bu, geliştirme sırasında veya sorun giderme aşamasında kullanışlıdır. docker compose up -d (detach modu) ise servisleri arka planda başlatır ve terminalinizi serbest bırakır. Bu genellikle uygulamanızı çalışır durumda bırakıp başka işlerle ilgilenmek istediğinizde tercih edilir. |
| Docker Compose üretim ortamında kullanılmalı mı? | Docker Compose, geliştirme ve test ortamları için mükemmel bir araçtır. Küçük ölçekli üretim ortamlarında veya tek sunuculu dağıtımlarda da kullanılabilir. Ancak büyük ölçekli, yüksek kullanılabilirlikli ve otomatik ölçeklenebilir üretim ortamları için Kubernetes gibi daha gelişmiş konteyner orkestrasyon araçları (örneğin Kubernetes) daha uygundur. Compose, bu tür daha karmaşık sistemlere geçiş için harika bir başlangıç noktasıdır. |
| Konteyner verilerini kalıcı hale getirmek için ne kullanmalıyım? | Konteyner verilerini kalıcı hale getirmek için Docker Volume’ları kullanmalısınız. İki ana türü vardır: adlandırılmış volume’lar (named volumes) ve bağlama noktaları (bind mounts). Adlandırılmış volume’lar, verileri Docker tarafından yönetilen özel bir alanda saklar ve konteyner silinse bile verilerin kaybolmamasını sağlar. Bind mount’lar ise ana makine dosya sistemindeki bir dizini doğrudan konteyner içine bağlar ve genellikle geliştirme sırasında kod değişikliklerinin anında yansıması için kullanılır. |