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 SiteleriYani 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-cmain-app, tüm müşteri siteleri için kaynak proje olsun. customer-a, customer-b, customer-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ı.
- .env, storage, uploads 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.comBu 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-betaMerkez veritabanında şu tablolar bulunabilir:
customer_servers
customer_sites
customer_site_deploy_batches
customer_site_deploymentscustomer_servers
Sunucuları temsil eder.
Örnek:
id: 1
slug: server-1
base_path: /var/www
status: activecustomer_sites
Müşteri sitelerini temsil eder.
Örnek:
id: 10
domain: https://customer-alpha.com
folder_name: customer-alpha
customer_server_id: 1Buradaki 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: 0customer_site_deployments
Her müşteri sitesi için ayrı deploy işini tutar.
Örnek:
batch_id: 1
customer_site_id: 10
status: pending
attempts: 0GitHub 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 }}
EOFBuradaki ö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_URLMerkez deploy sisteminin adresidir.
LICENSES_AGENT_SERVERBu sunucunun merkezdeki kimliğidir. Örneğin server-1.
LICENSES_AGENT_TOKENAgent’ın merkeze kendini doğrulamak için kullandığı token’dır.
SOURCE_PATHAna güncel kodun bulunduğu klasördür.
BASE_PATHMüşteri klasörlerinin bulunduğu ana dizindir.
POLL_INTERVALAgent’ın merkeze kaç saniyede bir soracağını belirtir.
UPDATE_SOURCE1 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-agentLog izleme:
tail -f /var/www/deploy-center/storage/logs/deploy-agent.logDeploy 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 --deleteKuyruk sayesinde işler sırayla ilerler:
customer-alpha -> completed
customer-beta -> running
customer-gamma -> pendingBu 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_messageBö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.confYanlış yer:
/var/www/customer-alpha/.env2. 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-onlykomutu 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-app4. 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-dataAgent 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üşteri sitelerine doğrudan deployment göndermek yerine, her müşteri sitesinin sıradaki güncelleme görevini kendisinin çekerek uyguladığı deploy yaklaşımıdır. Bu modelde güncellemeler bir kuyruğa alınır, siteler uygun zamanda bu kuyruğu kontrol ederek kendi gü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çin pratik olabilir. Ancak müşteri sitesi sayısı arttıkça her site için ayrı deploy işlemi başlatmak; süre, kaynak kullanımı, hata yönetimi ve izlenebilirlik açısından zorlaşabilir. Yüzlerce müşteri sitesi olan yapılarda merkezi kuyruk tabanlı yaklaşım daha kontrollü olabilir.</p>
Kuyruk ile çoklu müşteri sitesi güncellemenin avantajı nedir?
<p>Kuyruk yapısı sayesinde güncellemeler sıraya alınabilir, başarısız işlemler tekrar denenebilir, önceliklendirme yapılabilir ve hangi sitenin hangi sürümde olduğu daha kolay takip edilebilir. Bu da özellikle SaaS, çoklu müşteri paneli veya kopya site mimarilerinde daha güvenli bir deploy süreci sağlar.</p>
Pull Model Deploy güvenli midir?
<p>Doğru tasarlanırsa güvenli bir modeldir. Her müşteri sitesinin yalnızca yetkili olduğu güncelleme görevlerini çekmesi gerekir. Bunun için API token, domain doğrulama, IP kontrolü, imzalı artifact dosyaları, sürüm kontrolü ve loglama gibi güvenlik katmanları kullanılmalıdır.</p>
Bu model hangi projeler için uygundur?
<p>Pull Model Deploy; çok sayıda müşteri sitesi, bayi paneli, franchise yapısı, white-label SaaS sistemi veya aynı kod tabanından üretilmiş çoklu Laravel/Symfony projeleri için uygundur. Tek bir site veya küçük ölçekli projelerde GitHub Actions üzerinden klasik deploy yeterli olabilir.</p>
Bu kategorideki diğer yazılar
-
VPS Üzerinde Laravel AI Projesi Yayına Alma
19.04.2026