Takip et

Docker Compose’u Anlamak: Neden İhtiyacımız Var?

Ubuntu’da Docker Compose Kurulumu ve Kullanımı Rehberi

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.

Uzman İpucu: Docker Compose’un en büyük avantajlarından biri, geliştirme ortamları arasındaki “çalışıyor mu?” sorununu ortadan kaldırmasıdır. Her geliştirici, aynı 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:

  1. 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.
  2. 
    sudo apt-get remove docker docker-engine docker.io containerd runc
        

    Bu komut, sisteminizdeki eski Docker paketlerini kaldıracaktır.

  3. Gerekli Paketleri Yükleme: Docker deposunu kullanmak için bazı önkoşul paketlere ihtiyacımız var.
  4. 
    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.

  5. 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.
  6. 
    sudo mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
        
  7. Docker Deposunu Ekleme: Şimdi Docker’ın kararlı deposunu APT kaynaklarımıza ekleyebiliriz.
  8. 
    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).

  9. Docker Engine’i Yükleme: Depo eklendikten sonra, Docker Engine’i yükleyebiliriz.
  10. 
    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.

  11. Docker’ı Test Etme: Kurulumun başarılı olup olmadığını test etmek için bir “hello-world” konteynerini çalıştırabilirsiniz.
  12. 
    sudo docker run hello-world
        

    Eğer “Hello from Docker!” mesajını görürseniz, Docker başarıyla kurulmuş demektir.

  13. Docker Komutlarını Sudo Olmadan Çalıştırma (Önerilen): Her Docker komutunu sudo ile çalıştırmak zahmetli olabilir. Kullanıcınızı docker grubuna ekleyerek bu kısıtlamayı kaldırabilirsiniz.
  14. 
    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.

    1. Docker Compose’u İndirme: GitHub’daki Docker Compose deposundan en son kararlı sürümü indirin.
    2. 
      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.

    3. Çalıştırılabilir İzinleri Verme: İndirdiğiniz dosyaya çalıştırma izni vermeniz gerekir.
    4. 
      sudo chmod +x /usr/local/bin/docker-compose
          
    5. Kurulumu Doğrulama: Kurulumun başarılı olup olmadığını kontrol edin.
    6. 
      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:

    1. web/Dockerfile: Flask uygulamasını çalıştıracak Docker imajını tanımlar.
    2. 
      # 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.

    3. web/requirements.txt: Flask uygulamasının Python bağımlılıklarını içerir.
    4. 
      # web/requirements.txt
      Flask
      redis
          
    5. web/app.py: Basit bir Flask uygulaması. Redis’e bağlanmaya ve bir sayaç tutmaya çalışır.
    6. 
      # 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:

    • 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.
    • web servisi:
      • build: ./web: web dizinindeki Dockerfile‘ı kullanarak bir Docker imajı oluşturur.
      • ports: "5000:5000": Ana makinenin (host) 5000 portunu, web konteynerinin 5000 portuna eşler. Böylece tarayıcınızdan uygulamaya erişebilirsiniz.
      • volumes: ./web:/app: Yerel ./web dizinini konteyner içindeki /app dizinine 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: web servisinin başlamadan önce redis servisinin başlatılmasını beklediğini belirtir.
    • redis servisi:
      • image: "redis:latest": Docker Hub’dan resmi redis:latest imajı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çin redis_data adı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. Burada redis_data‘yı tanımlıyoruz.

    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
        
    • docker compose up: docker-compose.yml dosyası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.

    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:

    • 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_data adı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:/app bind mount kullandık.)

    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:

    • 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.

    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:

    • frontend servisi:
      • build: ./frontend: React uygulamasının statik dosyalarını oluşturan ve Nginx ile sunan bir Dockerfile‘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.
    • backend servisi:
      • build: ./backend: Node.js API’sini içeren bir Dockerfile‘dan imaj oluşturur.
      • environment: Veritabanı bağlantı bilgilerini ortam değişkenleri olarak ayarlar. Burada db hostname’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_modules istisnası, host’taki node_modules‘in konteynerdeki ile çakışmasını engeller.
    • db servisi:
      • 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ı özel app_network ağına dahil eder, böylece birbirleriyle kolayca iletişim kurabilirler.
    • volumes: db_data adında bir volume tanımlarız.

    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
        
    • --build: Gerekirse imajları yeniden oluşturur (örneğin, Dockerfile veya uygulama kodunda değişiklik yaptıysanız).

    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.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.