GitHub Matrix Yerine Pull Model Deploy: Çoklu Müşteri Sitelerini Kuyruk ile Güncellemek

Bir SaaS veya çoklu müşteri sitesi yapısında sık karşılaşılan problemlerden biri şudur:

Ana projede yaptığım değişikliği, aynı altyapıyı kullanan tüm müşteri sitelerine nasıl güvenli ve kontrollü dağıtırım?

İlk akla gelen çözüm genelde GitHub Actions matrix deploy olur. Örneğin her müşteri sitesi veya her sunucu için GitHub workflow içinde ayrı deploy adımları çalıştırılır. Bu küçük yapılarda iş görebilir, fakat müşteri sayısı arttıkça yönetimi zorlaşır.

Bu yazıda alternatif bir yaklaşımı ele alacağız:

 
Merkez Deploy Sistemi ↓ Deploy Kuyruğu ↓ Sunucu Agent'ları ↓ Müşteri Siteleri

Yani GitHub her müşteri sitesine tek tek bağlanmaz. Bunun yerine merkez sistemde bir kuyruk oluşturulur. Her sunucuda çalışan küçük bir agent, merkeze düzenli olarak sorar:

Bana ait güncelleme işi var mı?

Varsa işi alır, kendi sunucusundaki müşteri sitelerini sırayla günceller.

Problem

Elimizde şöyle bir yapı olduğunu düşünelim:

 
/var/www/main-app /var/www/customer-a /var/www/customer-b /var/www/customer-c

main-app, tüm müşteri siteleri için kaynak proje olsun. customer-acustomer-bcustomer-c ise aynı kod tabanını kullanan müşteri siteleri.

Ana projede bir değişiklik yaptığımızda bu değişiklikleri tüm müşteri klasörlerine aktarmak istiyoruz. Ama bazı önemli şartlarımız var:

  • Müşteri veritabanındaki içerikler korunmalı.
  • .envstorageuploads gibi müşteri özel dosyaları silinmemeli.
  • Güncellemeler aynı anda patlamamalı, sırayla ilerlemeli.
  • Hangi site güncellendi, hangisi hata aldı takip edilebilmeli.
  • İleride birden fazla VPS sunucu desteklenebilmeli.

Neden GitHub Matrix Değil?

GitHub matrix ile şöyle bir yapı kurulabilir:

 
strategy: matrix: server: - host: server-1.example.com - host: server-2.example.com - host: server-3.example.com

Bu yaklaşımda GitHub Actions her sunucuya bağlanır ve deploy yapar.

Ancak müşteri sayısı büyüdükçe bazı dezavantajlar oluşur:

  • GitHub workflow dosyası sunucu/müşteri listesiyle şişer.
  • Deploy kontrolü GitHub tarafında kalır.
  • Her sunucuya SSH erişimi GitHub üzerinden yönetilir.
  • 50-100 müşteri sitesinde aynı anda yük oluşabilir.
  • Hata durumunda tekrar deneme ve raporlama zorlaşır.
  • Merkezde “hangi müşteri hangi durumda?” bilgisini tutmak için ek yapı gerekir.

Bu yüzden pull model daha kontrollü bir alternatiftir.

Pull Model Nedir?

Pull modelde merkez sistem sunuculara bağlanmaz. Tam tersi, her müşteri sunucusunda çalışan agent merkeze bağlanır.

 
Agent -> Merkez: Bana ait iş var mı? Merkez -> Agent: Evet, customer-a sitesini güncelle. Agent -> Kendi sunucusu: /var/www/main-app içeriğini /var/www/customer-a içine uygula. Agent -> Merkez: İş tamamlandı veya hata aldı.

Bu modelin avantajları:

  • Merkez sunuculara SSH açmak zorunda kalmaz.
  • Her sunucu sadece kendi işlerini çeker.
  • Firewall/NAT sorunları azalır.
  • İşler sırayla yürütülebilir.
  • Merkezi raporlama yapılabilir.
  • 10 sunucu, 100 müşteri gibi yapılar daha rahat ölçeklenir.

Örnek Mimari

Demo olarak şöyle düşünelim:

 
Merkez uygulama: https://deploy.example.com Ana kaynak proje: https://github.com/demo-org/main-app Sunucu: server-1 Sunucu içindeki klasörler: /var/www/main-app /var/www/customer-alpha /var/www/customer-beta

Merkez veritabanında şu tablolar bulunabilir:

 
customer_servers customer_sites customer_site_deploy_batches customer_site_deployments

customer_servers

Sunucuları temsil eder.

Örnek:

 
id: 1 slug: server-1 base_path: /var/www status: active

customer_sites

Müşteri sitelerini temsil eder.

Örnek:

 
id: 10 domain: https://customer-alpha.com folder_name: customer-alpha customer_server_id: 1

Buradaki customer_server_id, bu sitenin hangi VPS üzerinde olduğunu gösterir.

customer_site_deploy_batches

Bir deploy çalışmasını temsil eder.

Örnek:

 
uuid: 81c7... source_ref: 9f2a1cd status: running total_sites: 2 completed_sites: 1 failed_sites: 0

customer_site_deployments

Her müşteri sitesi için ayrı deploy işini tutar.

Örnek:

 
batch_id: 1 customer_site_id: 10 status: pending attempts: 0

GitHub Workflow Ne Yapar?

GitHub workflow sadece ana projeyi canlıya deploy eder ve ardından merkezde kuyruk oluşturur.

Örnek:

 
- name: Deploy main app run: | rsync -avz ./ deploy@server:/var/www/main-app/ - name: Queue customer site updates run: | ssh deploy@server << EOF cd /var/www/deploy-center php artisan customer-sites:queue-deploy-updates --source-ref=${{ github.sha }} EOF

Buradaki önemli nokta şu:

 
php artisan customer-sites:queue-deploy-updates --source-ref=${{ github.sha }}

Bu komut müşteri sitelerini doğrudan güncellemez. Sadece merkez sistemde deploy kuyruğu oluşturur.

Agent Ne Yapar?

Her sunucuda çalışan agent şunu yapar:

 
1. Merkeze sorar: Bana ait bekleyen iş var mı? 2. İş varsa alır. 3. Gerekirse /var/www/main-app klasörünü git pull ile günceller. 4. Kaynak kodu müşteri klasörüne rsync ile aktarır. 5. composer install çalıştırır. 6. php artisan migrate --force çalıştırır. 7. cache temizler. 8. Sonucu merkeze bildirir.

Örnek agent değişkenleri:

 
LICENSES_AGENT_URL="https://deploy.example.com" LICENSES_AGENT_SERVER="server-1" LICENSES_AGENT_TOKEN="secret-agent-token" SOURCE_PATH="/var/www/main-app" BASE_PATH="/var/www" POLL_INTERVAL="30" UPDATE_SOURCE="0" USE_SUDO="0"

Değişkenler Ne İşe Yarar?

 
LICENSES_AGENT_URL

Merkez deploy sisteminin adresidir.

 
LICENSES_AGENT_SERVER

Bu sunucunun merkezdeki kimliğidir. Örneğin server-1.

 
LICENSES_AGENT_TOKEN

Agent’ın merkeze kendini doğrulamak için kullandığı token’dır.

 
SOURCE_PATH

Ana güncel kodun bulunduğu klasördür.

 
BASE_PATH

Müşteri klasörlerinin bulunduğu ana dizindir.

 
POLL_INTERVAL

Agent’ın merkeze kaç saniyede bir soracağını belirtir.

 
UPDATE_SOURCE

1 ise agent önce git pull yapar.
0 ise mevcut kaynak klasörü kullanır.

Tek sunuculu yapıda GitHub zaten /var/www/main-app klasörünü güncelliyorsa genellikle şu yeterlidir:

 
UPDATE_SOURCE="0"

Farklı VPS’lerde her sunucu kendi kaynak kodunu GitHub’dan çekecekse:

 
UPDATE_SOURCE="1"

kullanılabilir.

Rsync Neden Kullanılır?

Kodları müşteri klasörüne aktarırken bazı dosyaları korumak gerekir.

Örnek:

 
rsync -a --delete \ --exclude='.env' \ --exclude='.git/' \ --exclude='storage/' \ --exclude='bootstrap/cache/' \ --exclude='public/uploads/' \ --exclude='public/storage/' \ --exclude='node_modules/' \ --exclude='vendor/' \ "$SOURCE_PATH/" "$TARGET_PATH/"

Burada amaç:

  • Kod dosyalarını güncellemek
  • Müşteri özel .env dosyasını korumak
  • Upload edilen dosyaları silmemek
  • Storage içeriğini ezmemek
  • Vendor klasörünü müşteri tarafında yeniden kurmak

Supervisor ile Agent Çalıştırmak

Agent’ın sürekli çalışması için Supervisor kullanılabilir.

Örnek config:

 
[program:deploy-agent] process_name=%(program_name)s command=/bin/bash /var/www/deploy-center/customer-deploy-agent.sh directory=/var/www/deploy-center autostart=true autorestart=true user=www-data redirect_stderr=true stdout_logfile=/var/www/deploy-center/storage/logs/deploy-agent.log stopwaitsecs=3600 environment=LICENSES_AGENT_URL="https://deploy.example.com",LICENSES_AGENT_SERVER="server-1",LICENSES_AGENT_TOKEN="secret-token",SOURCE_PATH="/var/www/main-app",BASE_PATH="/var/www",POLL_INTERVAL="30",UPDATE_SOURCE="0",USE_SUDO="0"

Aktifleştirmek için:

 
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl restart deploy-agent

Log izleme:

 
tail -f /var/www/deploy-center/storage/logs/deploy-agent.log

Deploy Sırası

Tam akış şöyle olur:

 
1. Developer GitHub’a push yapar. 2. GitHub Actions main-app klasörünü günceller. 3. Workflow merkez sisteme deploy kuyruğu oluşturur. 4. Agent merkeze “iş var mı?” diye sorar. 5. Merkez sıradaki müşteri sitesini döner. 6. Agent siteyi günceller. 7. Composer, migrate ve cache işlemleri çalışır. 8. Sonuç merkeze yazılır. 9. Agent sıradaki işe geçer.

Neden Kuyruk?

10 müşteri sitesini aynı anda güncellemek küçük sunucularda risklidir.

Özellikle şu işlemler yük bindirir:

 
composer install php artisan migrate php artisan optimize:clear rsync --delete

Kuyruk sayesinde işler sırayla ilerler:

 
customer-alpha -> completed customer-beta -> running customer-gamma -> pending

Bu da sunucu yükünü daha kontrollü hale getirir.

Loglama ve Raporlama

Her deploy için şu bilgiler tutulabilir:

 
status attempts assigned_at started_at heartbeat_at finished_at output error_message

Böylece panelden şu sorular cevaplanabilir:

  • Hangi site güncellendi?
  • Hangi site hata aldı?
  • Hata composer’da mı, migration’da mı, rsync’te mi?
  • Agent en son ne zaman merkeze bağlandı?
  • Hangi GitHub commit’i dağıtıldı?

Dikkat Edilmesi Gerekenler

1. Token Güvenliği

Agent token sadece sunucu tarafında tutulmalıdır. Müşteri sitesinin .env dosyasına yazılmamalıdır.

Doğru yer:

 
/etc/supervisor/conf.d/deploy-agent.conf

Yanlış yer:

 
/var/www/customer-alpha/.env

2. Git Pull Yetkisi

Eğer agent UPDATE_SOURCE=1 ile çalışıyorsa, ilgili kullanıcı GitHub’a erişebilmelidir.

Örneğin agent www-data ile çalışıyorsa:

 
sudo -u www-data git -C /var/www/main-app pull --ff-only

komutu başarılı olmalıdır.

Eğer GitHub kullanıcı adı soruyorsa, deploy key veya SSH remote ayarlanmalıdır.

3. Safe Directory Hatası

Git bazen şu hatayı verebilir:

 
fatal: detected dubious ownership in repository

Çözüm:

 
sudo -u www-data git config --global --add safe.directory /var/www/main-app

4. Composer HOME Hatası

www-data ile composer çalışırken şu hata gelebilir:

 
The HOME or COMPOSER_HOME environment variable must be set

Çözüm:

 
export COMPOSER_HOME=/tmp/composer-www-data

Agent script içinde bu ayarlanabilir.

Sonuç

GitHub matrix deploy küçük yapılarda kullanışlı olabilir, ancak çok müşterili yapılarda merkezi kuyruk ve pull model daha kontrollü bir çözüm sunar.

Bu yapı sayesinde:

  • GitHub sadece ana deploy’u tetikler.
  • Merkez sistem deploy kuyruğunu yönetir.
  • Her sunucu kendi işlerini çeker.
  • Müşteri siteleri sırayla güncellenir.
  • Loglama ve raporlama merkezi yapılır.
  • İleride 10 sunucu, 100 müşteri gibi yapılara daha rahat ölçeklenir.

Kısaca:

 
GitHub deploy eder. Merkez sıraya koyar. Agent çeker. Sunucu kendi müşterilerini günceller. Merkez sonucu raporlar.

Bu yaklaşım, müşteri verisini koruyarak çoklu site güncellemelerini daha güvenli, izlenebilir ve ölçeklenebilir hale getirir.

Keywords: Deploy, blog, Laravel, PHP, GitHub Matrix Yerine Pull Model Deploy: Çoklu Müşteri Sitelerini Kuyruk ile Güncellemek

Sıkça Sorulan Sorular

Pull Model Deploy nedir?

<p>Pull Model Deploy, merkezi bir kaynaktan m&uuml;şteri sitelerine doğrudan deployment g&ouml;ndermek yerine, her m&uuml;şteri sitesinin sıradaki g&uuml;ncelleme g&ouml;revini kendisinin &ccedil;ekerek uyguladığı deploy yaklaşımıdır. Bu modelde g&uuml;ncellemeler bir kuyruğa alınır, siteler uygun zamanda bu kuyruğu kontrol ederek kendi g&uuml;ncellemesini başlatır.</p>

GitHub Actions Matrix deploy neden her zaman ideal değildir?

<p>GitHub Actions Matrix, az sayıda hedef ortam i&ccedil;in pratik olabilir. Ancak m&uuml;şteri sitesi sayısı arttık&ccedil;a her site i&ccedil;in ayrı deploy işlemi başlatmak; s&uuml;re, kaynak kullanımı, hata y&ouml;netimi ve izlenebilirlik a&ccedil;ısından zorlaşabilir. Y&uuml;zlerce m&uuml;şteri sitesi olan yapılarda merkezi kuyruk tabanlı yaklaşım daha kontroll&uuml; olabilir.</p>

Kuyruk ile çoklu müşteri sitesi güncellemenin avantajı nedir?

<p>Kuyruk yapısı sayesinde g&uuml;ncellemeler sıraya alınabilir, başarısız işlemler tekrar denenebilir, &ouml;nceliklendirme yapılabilir ve hangi sitenin hangi s&uuml;r&uuml;mde olduğu daha kolay takip edilebilir. Bu da &ouml;zellikle SaaS, &ccedil;oklu m&uuml;şteri paneli veya kopya site mimarilerinde daha g&uuml;venli bir deploy s&uuml;reci sağlar.</p>

Pull Model Deploy güvenli midir?

<p>Doğru tasarlanırsa g&uuml;venli bir modeldir. Her m&uuml;şteri sitesinin yalnızca yetkili olduğu g&uuml;ncelleme g&ouml;revlerini &ccedil;ekmesi gerekir. Bunun i&ccedil;in API token, domain doğrulama, IP kontrol&uuml;, imzalı artifact dosyaları, s&uuml;r&uuml;m kontrol&uuml; ve loglama gibi g&uuml;venlik katmanları kullanılmalıdır.</p>

Bu model hangi projeler için uygundur?

<p>Pull Model Deploy; &ccedil;ok sayıda m&uuml;şteri sitesi, bayi paneli, franchise yapısı, white-label SaaS sistemi veya aynı kod tabanından &uuml;retilmiş &ccedil;oklu Laravel/Symfony projeleri i&ccedil;in uygundur. Tek bir site veya k&uuml;&ccedil;&uuml;k &ouml;l&ccedil;ekli projelerde GitHub Actions &uuml;zerinden klasik deploy yeterli olabilir.</p>

Bu kategorideki diğer yazılar

Yorumlar

Log in or sign up to write a comment
Giriş
Sign Up