Docker & DevOps

    Blue-Green Deployment Nedir

    İki özdeş üretim ortamı arasında trafiği çevirerek risksiz yayın yapma yöntemi.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Yeni sürümü canlıya aldın, beş dakika sonra telefon çalıyor: ödeme sayfası hata veriyor. Geri almak için commit'i geri alıp yeniden derleme ve yeniden dağıtım derken yirmi dakika geçti ve o yirmi dakika boyunca kimse sipariş veremedi. Blue-green deployment tam olarak bu senaryoyu ortadan kaldırmak için vardır: iki özdeş üretim ortamı tutarsın, yeni sürümü kimse görmeden ayağa kaldırırsın, hazır olduğunda trafiği saniyeler içinde çevirirsin ve bir sorun çıkarsa aynı hızla geri alırsın.

    Bu rehberde blue-green deployment'ın mantığını, trafiği çeviren yönlendirme katmanının nasıl kurulduğunu, Nginx ve Docker Compose ile gerçek bir kurulumun nasıl göründüğünü, işin en zor parçası olan veritabanı şema değişikliklerini nasıl yöneteceğini ve sahada en çok gördüğüm hataları anlatacağım. Amacım, yazının sonunda kendi altyapında iki renkli bir yayın hattı kurabilecek kadar somut bilgiye sahip olman.

    Blue-Green Deployment Tam Olarak Nedir#

    Blue-green deployment, aynı uygulamanın iki bağımsız kopyasını sürekli hazır tutma fikrine dayanır. Bu kopyalara geleneksel olarak "blue" ve "green" denir; renklerin bir anlamı yoktur, sadece hangisinin canlı olduğunu karıştırmadan konuşabilmek içindir. Herhangi bir anda bunlardan yalnızca biri gerçek kullanıcı trafiğini alır. Diğeri boşta bekler ve bir sonraki sürümün hazırlanacağı yerdir. Dağıtım dediğin şey artık "sunucudaki dosyaları değiştirmek" değil, "boştaki ortama yeni sürümü kurmak, test etmek ve yönlendirmeyi ona çevirmek" haline gelir.

    Bu yaklaşımın kazandırdığı en büyük şey hız değil, geri dönebilirliktir. Klasik dağıtımda geri almak, yeni bir dağıtım yapmak demektir; yani aynı riski bir kez daha almaktır. Blue-green'de eski sürüm hâlâ ayakta, çalışıyor ve ısınmış durumda olduğu için geri dönüş sadece yönlendirmeyi eski renge çevirmekten ibarettir. Pratikte bu saniyeler sürer. Aşağıdaki tablo iki ortamın tipik yaşam döngüsünü özetler.

    AşamaBlue (canlı)Green (boşta)Kullanıcı ne görür
    Normal işleyişv1.4 – trafik %100v1.4 – trafik yokv1.4
    Hazırlıkv1.4 – trafik %100v1.5 kuruluyorv1.4
    Duman testiv1.4 – trafik %100v1.5 – iç testlerv1.4
    Geçişv1.4 – trafik yokv1.5 – trafik %100v1.5
    Sorun çıkarsav1.4 – trafik %100v1.5 – trafik yoktekrar v1.4

    Trafiği Çeviren Katman: Yönlendiricinin Rolü#

    Blue-green'in tamamı, önündeki yönlendirme katmanının ne kadar hızlı ve atomik biçimde hedef değiştirebildiğine bağlıdır. Bu katman bir Nginx ya da HAProxy olabilir, bulut sağlayıcının yük dengeleyicisi olabilir, hatta DNS bile olabilir. Ama DNS'i bu iş için önermiyorum: TTL yüzünden geçiş anlık değildir ve dünyanın bir kısmı dakikalarca eski ortamı görmeye devam eder; geri dönüş de aynı gecikmeyle yavaşlar. Yönlendirme kararını uygulamanın hemen önündeki bir ters vekil (reverse proxy) versin.

    Nginx tarafında en temiz kurulum, aktif hedefi ayrı bir dosyada tutup ana yapılandırmadan dahil etmektir. Böylece geçiş, tek bir dosyayı değiştirip Nginx'e nazikçe yeniden yükleme sinyali göndermeye indirgenir; mevcut istekler kesilmez, yeni istekler yeni hedefe gider.

    # /etc/nginx/conf.d/upstream-active.conf
    # Bu dosyanın tek işi hangi rengin canlı olduğunu söylemek.
    upstream app_active {
        server 127.0.0.1:8081;   # blue  -> 8081
        # server 127.0.0.1:8082; # green -> 8082
    }
    
    # /etc/nginx/conf.d/firmaniz.conf
    server {
        listen 443 ssl http2;
        server_name firmaniz.com;
    
        location / {
            proxy_pass http://app_active;
            proxy_set_header Host              $host;
            proxy_set_header X-Real-IP         $remote_addr;
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            # Geçiş anında yarım kalan istekleri diğer hedefe devret
            proxy_next_upstream error timeout http_502 http_503;
        }
    }
    

    Nginx ile Adım Adım Geçiş#

    Aşağıdaki akış, elle de betikle de aynı şekilde işler. Önemli olan sırayı bozmamaktır; özellikle sağlık kontrolünü geçişten önce yapmak, blue-green'i "iki ortamlı klasik dağıtım"dan ayıran şeydir.

    1. Boştaki rengi belirle. Aktif dosyada hangi portun açık olduğuna bak; canlı 8081 ise hedefin 8082 olacak.
    2. Yeni sürümü boştaki ortama kur ve başlat. Uygulama ayağa kalkana kadar bekle.
    3. Duman testi (smoke test) yap. En az bir sağlık uç noktası, bir okuma sayfası ve bir yazma işlemi dene.
    4. Aktif dosyadaki yorum satırlarını değiştirerek hedefi yeni renge çevir.
    5. nginx -t ile söz dizimini doğrula, ardından systemctl reload nginx çalıştır.
    6. İlk beş dakika hata oranını ve yanıt süresini izle. Bozulma varsa 4. adımı ters yönde uygula.
    #!/usr/bin/env bash
    set -euo pipefail
    
    ACTIVE_FILE=/etc/nginx/conf.d/upstream-active.conf
    # Şu an hangi port canlı?
    if grep -q "^\s*server 127.0.0.1:8081;" "$ACTIVE_FILE"; then
      LIVE=8081; NEXT=8082
    else
      LIVE=8082; NEXT=8081
    fi
    echo "Canlı: $LIVE | Hedef: $NEXT"
    
    # 1) Boştaki ortamın sağlığını doğrula (10 deneme, 2 sn arayla)
    for i in $(seq 1 10); do
      if curl -fsS "http://127.0.0.1:${NEXT}/healthz" >/dev/null; then
        echo "Sağlık kontrolü geçti."; break
      fi
      [ "$i" -eq 10 ] && { echo "Yeni ortam sağlıklı değil, geçiş iptal."; exit 1; }
      sleep 2
    done
    
    # 2) Yönlendirmeyi çevir
    printf 'upstream app_active {\n    server 127.0.0.1:%s;\n}\n' "$NEXT" > "$ACTIVE_FILE"
    
    # 3) Doğrula ve nazikçe yeniden yükle
    nginx -t && systemctl reload nginx
    echo "Trafik $NEXT portuna çevrildi."
    

    Bu betiğin en kıymetli satırı exit 1 olanıdır: yeni ortam sağlıklı değilse geçiş hiç yapılmaz ve kullanıcı hiçbir şey fark etmez. Kesintisiz yayının genel prensiplerini ayrıca sıfır kesintili deploy yazısında ele aldım.

    Docker Compose ile İki Rengi Ayakta Tutmak#

    Konteyner kullanıyorsan blue-green kurmak daha da kolaydır, çünkü iki sürümü yan yana çalıştırmak zaten Docker'ın doğal davranışıdır. Tek yapman gereken iki servisi farklı portlara bağlamak ve imaj etiketlerini ayrı tutmaktır. Aşağıdaki dosya, aynı uygulamanın iki rengini tek bir Compose projesinde tanımlar.

    # docker-compose.yml
    services:
      app-blue:
        image: firmaniz/api:1.4.0
        ports: ["127.0.0.1:8081:3000"]
        env_file: .env
        restart: unless-stopped
        healthcheck:
          test: ["CMD", "curl", "-fsS", "http://localhost:3000/healthz"]
          interval: 10s
          timeout: 3s
          retries: 5
    
      app-green:
        image: firmaniz/api:1.5.0
        ports: ["127.0.0.1:8082:3000"]
        env_file: .env
        restart: unless-stopped
        healthcheck:
          test: ["CMD", "curl", "-fsS", "http://localhost:3000/healthz"]
          interval: 10s
          timeout: 3s
          retries: 5
    

    Yeni sürüme geçerken yalnız hedef rengin imaj etiketini güncelleyip docker compose up -d app-green çalıştırırsın; diğer servise dokunmadığı için canlı trafik etkilenmez. Compose'un servis bazlı çalışma mantığına ve depends_on gibi ayrıntılara aşina değilsen Docker Compose kullanımı yazısı iyi bir başlangıç noktası. Konteyner sürekli yeniden başlıyorsa geçişi hiç denemeden önce bu sorunun nedenlerine bakmanı öneririm; sağlıksız bir yeşil ortamı canlıya almak, blue-green'in sağladığı tüm güvenliği tek hamlede harcar.

    Veritabanı: İşin Asıl Zor Kısmı#

    Uygulama kodunu iki kopya halinde tutmak kolaydır, veritabanını değildir. Çoğu kurulumda blue ve green aynı veritabanına bağlanır, çünkü iki ayrı veritabanı tutarsan geçiş anında yazılan veriyi kaybedersin. Bu da şu anlama gelir: şema, hem eski hem yeni sürümle aynı anda uyumlu olmak zorundadır. Bir sütunu silen ya da adını değiştiren tek bir migrasyon, geri dönüşünü imkânsız hale getirir.

    Çözüm, şema değişikliklerini genişlet-daralt (expand/contract) düzeninde iki dağıtıma yaymaktır. Önce yeni yapıyı ekleyip eskisini bırakırsın, iki sürüm bir süre birlikte yaşar, eski sürüm tamamen emekli olduktan sonra bir sonraki dağıtımda eski yapıyı silersin.

    -- 1. DAĞITIM (genişlet): yeni sütunu ekle, eskisine dokunma
    ALTER TABLE siparisler ADD COLUMN musteri_eposta VARCHAR(255) NULL;
    -- Uygulama v1.5 hem eski hem yeni sütuna yazar, okurken yeniyi tercih eder.
    
    UPDATE siparisler SET musteri_eposta = eposta WHERE musteri_eposta IS NULL;
    
    -- 2. DAĞITIM (daralt): v1.4 tamamen emekli olduktan SONRA
    ALTER TABLE siparisler DROP COLUMN eposta;
    

    İkinci kural da şudur: uzun süren migrasyonları geçişin kritik yoluna koyma. Milyonlarca satırlık bir tabloya indeks eklemek dakikalar sürebilir ve bu süre boyunca tablo kilitlenebilir. Bu tür işlemleri dağıtımdan önce, düşük trafikli bir saatte ve mümkünse eşzamanlı (concurrent) indeks oluşturma yöntemiyle ayrı çalıştır. Geçiş anında veritabanına dokunulmuyor olması, blue-green'in gerçekten saniyeler içinde geri alınabilmesinin ön koşuludur. Kritik bir şema değişikliğinden önce mutlaka doğrulanmış bir yedek al; yedekleme hizmetimiz bu tür anlarda geri dönüş güvencesi sağlar.

    Sık Yapılan Hatalar ve Tuzaklar#

    Sahada gördüğüm ilk hata, iki ortamın gerçekten özdeş olmamasıdır. Green ortamında farklı bir çalışma zamanı sürümü, eksik bir ortam değişkeni ya da farklı bir dosya izni varsa, testler geçse bile canlıda beklenmedik davranış çıkar. İki ortamı da aynı imajdan, aynı yapılandırma kaynağından ve aynı betikle üretmek zorundasın; "elle bir dokunuş" yapılan ortam blue-green'in en zayıf halkasıdır.

    İkinci hata, oturum ve önbellek durumunu ortama bağlı tutmaktır. Oturumları uygulama sunucusunun belleğinde saklıyorsan geçiş anında tüm kullanıcıların oturumu düşer; kullanıcı için bu, kesinti kadar rahatsız edicidir. Oturumu Redis gibi paylaşılan bir yerde tut, yüklenen dosyaları konteynerin içine değil ortak bir birime yaz. Diğer sık tuzakları da şöyle sıralayabilirim:

    • Sağlık uç noktasının yüzeysel olması. Yalnızca "sunucu ayakta mı" diyen bir /healthz, veritabanına bağlanamayan bir sürümü sağlıklı gösterir. Uç nokta en azından veritabanı ve önbellek bağlantısını yoklamalı.
    • Eski rengi hemen kapatmak. Geçişten sonra en az bir saat, tercihen bir gün eski ortamı ayakta bırak; asıl sigortan odur.
    • Zamanlanmış görevlerin iki kez çalışması. Her iki renk de cron çalıştırıyorsa aynı iş iki kez yapılır. Zamanlanmış işleri yalnızca aktif renkte etkinleştir ya da ayrı bir işçi düğümüne taşı.
    • Kaynak yetersizliği. İki ortam iki kat bellek demektir. Sunucun tek bir kopyayı zar zor kaldırıyorsa geçiş anında ikisi birden çöker.

    Blue-Green mi, Canary mi, Rolling mi#

    Üç yöntem de kesintisiz yayın hedefler ama farklı risk profilleri sunar. Blue-green kararı ikili verir: ya hepsi eski sürümü görür ya hepsi yenisini. Bu, geri dönüşü basitleştirir ama yeni sürümün hatalarını gerçek trafikle kademeli keşfetme şansını vermez. Canary deployment trafiğin küçük bir yüzdesini yeni sürüme yönlendirerek bu boşluğu doldurur; rolling update ise örnekleri teker teker değiştirerek ek kaynak ihtiyacını azaltır.

    ÖlçütBlue-GreenCanaryRolling
    Ek kaynak ihtiyacıYüksek (iki kat)OrtaDüşük
    Geri dönüş hızıSaniyelerSaniyelerDakikalar
    Kademeli risk ölçümüYokVarKısmen
    Kurulum karmaşıklığıDüşükOrtaOrta
    İki sürüm aynı anda çalışır mıEvet (trafik tek renkte)EvetEvet

    Pratikte bu üçü birbirinin alternatifi değil, tamamlayıcısıdır. Küçük ve orta ölçekli kurulumlarda blue-green ile başlamanı, trafik büyüyüp risk toleransı düştüğünde geçişin son adımına kademeli bir canary yüzdesi eklemeni öneririm.

    Sıkça Sorulan Sorular#

    Blue-green deployment iki katı sunucu maliyeti demek mi#

    Geçiş anında evet, iki ortam da ayakta olduğu için kaynak kullanımı iki katına yaklaşır. Ancak boştaki ortamı sürekli tam kapasitede tutmak zorunda değilsin; birçok ekip yeşil ortamı yalnızca dağıtım penceresinde ayağa kaldırıp geçişten bir gün sonra kapatır. Konteynerle çalışıyorsan boştaki kopya çok az bellek tüketir ve maliyet farkı pratikte düşünülenden çok daha küçük kalır.

    Geçişten sonra eski ortamı ne kadar süre ayakta tutmalıyım#

    Genel kuralım en az bir tam iş günüdür. Hataların önemli bir kısmı ilk dakikalarda değil, gün içindeki trafik zirvesinde ya da gece çalışan bir toplu işte ortaya çıkar. Eski ortam ayakta durduğu sürece geri dönüş tek komutluk bir iştir; kapattığın anda yeniden kurmak zorunda kalırsın. Kaynak sıkıntın varsa eski ortamı kapatmak yerine ölçeğini küçültmeyi tercih et.

    Veritabanı migrasyonlarını geçişten önce mi sonra mı çalıştırmalıyım#

    Şemayı genişleten migrasyonları geçişten önce çalıştır; yeni sürüm ayağa kalktığında ihtiyacı olan sütunlar hazır olsun. Eski yapıyı silen migrasyonları ise eski sürüm tamamen emekli olduktan sonra, bir sonraki dağıtımda çalıştır. Bu iki adımlı düzen sayesinde her iki sürüm de aynı şema üzerinde çalışabilir ve geri dönüş veritabanı yüzünden imkânsız hale gelmez.

    DNS ile blue-green yapabilir miyim#

    Teknik olarak yapabilirsin ama önermiyorum. DNS kayıtları çözümleyicilerde TTL süresince önbelleğe alınır, dolayısıyla geçiş anlık olmaz ve kullanıcıların bir kısmı dakikalarca hatta saatlerce eski ortamı görmeye devam eder. Daha kötüsü, geri dönüş de aynı gecikmeye tabidir. Yönlendirme kararını Nginx, HAProxy gibi bir ters vekil ya da yük dengeleyici katmanında ver; DNS'i yalnızca en dış katman değişikliklerinde kullan.

    WebSocket ve uzun süreli bağlantılar geçişte ne olur#

    Yeniden yükleme sırasında mevcut bağlantılar eski hedefe bağlı kalmaya devam eder, yeni bağlantılar yeni renge gider. Bu, HTTP istekleri için sorunsuzdur ama saatlerce açık kalan WebSocket bağlantıları için eski ortamı kapatmanı geciktirir. Çözüm, istemci tarafında otomatik yeniden bağlanma uygulamak ve eski ortamı kapatmadan önce bağlantı sayısının düşmesini beklemektir.

    Küçük bir siteye blue-green kurmak aşırıya kaçmak olur mu#

    Trafiği düşük, tek sayfalık bir tanıtım sitesi için gereksiz olabilir. Ama sipariş alan, form kabul eden ya da giriş yapılan her sistemde birkaç dakikalık kesinti gerçek bir maliyettir ve blue-green'in kurulum maliyeti oldukça düşüktür: iki port, bir Nginx dosyası ve yirmi satırlık bir betik. Küçük bir kurulumda bile geri dönüşün saniyeler sürmesi, gece yarısı yaşanacak paniği ortadan kaldırır.

    Kapanış#

    Blue-green deployment'ın özü karmaşık araçlar değil, birkaç sağlam alışkanlıktır: iki ortamı gerçekten özdeş tutmak, yönlendirmeyi tek ve atomik bir noktadan çevirmek, geçişten önce anlamlı bir sağlık kontrolü çalıştırmak ve şema değişikliklerini genişlet-daralt düzeninde iki dağıtıma yaymak. Bunları oturttuğunda yayın günü stresli bir olay olmaktan çıkar, sıradan bir işleme dönüşür. Eski ortamı bir gün ayakta bırakmayı da unutma; asıl sigortan odur.

    İki ortamı rahatça yan yana çalıştıracak kaynağa ihtiyacın varsa tam root erişimli VDS ve bulut sunucu paketlerimiz bu tür kurulumlar için uygun bir başlangıç noktası. Nginx yapılandırmasını, sağlık kontrollerini ve geçiş betiklerini kendin kurmak istemiyorsan sunucu yönetimi hizmetimiz bu işi sizin yerinize üstlenir; kritik şema değişikliklerinden önce geri dönüş güvencesi için de yedekleme çözümlerimize göz atabilirsin.

    DeploymentNginxDevOps

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.