CI/CD boru hatlarını (pipelines) ayağa kaldırırken hemen hemen her ekibin düştüğü bir ikilem vardır: Altyapıyı SaaS sağlayıcıların hazır makinelerine mi bırakmalı, yoksa kendi sunucularımızda koşan self-hosted runner sistemini mi kurmalı? İlk bakışta “kendi VPS sunucuma kurar, sınırsız dakika kullanırım, faturadan kurtulurum” düşüncesi çok cazip gelse de, işin aslı her zaman öyle toz pembe olmuyor. Bu rehberde, Self-Hosted Runner vs SaaS karşılaştırmasını sadece sunucu faturaları üzerinden değil; gizli ağ maliyetleri, bakım eforu, disk yönetimi ve güvenlik başlıkları altında, saha tecrübemle masaya yatırıyorum.
Üretim ortamlarında kendi geliştirdiğim yan ürünlerin backend servislerini deploy ederken her iki yöntemi de defalarca kullandım, patlattım ve optimize ettim. Hangi senaryoda hangi seçimin cüzdanınızı ve vaktinizi koruyacağını inceleyelim.
1. Maliyet Denklemine Giriş: Gizli Faturalar ve Donanım Amortismanı
Çoğu yazılımcı ve sistem yöneticisi maliyet hesabı yaparken SaaS platformların ücretsiz limitlerini veya dakika başına biçtiği standart tarifeleri temel alıyor. Örneğin, popüler bir SaaS CI/CD platformunda standart 2 vCPU, 8 GB RAM makinenin dakikası ortalama $0.008 civarındadır. Günde 100 build alan ve her build’i ortalama 10 dakika süren orta ölçekli bir ekibin aylık tüketimi yaklaşık 30.000 dakika yapar. Bu da doğrudan $240 fatura demektir.
Buna karşılık, aylık $40 ödediğiniz 8 vCPU ve 16 GB RAM’e sahip bir VPS üzerinde kendi runner’ınızı çalıştırdığınızda kağıt üzerinde $200 tasarruf ettiğinizi sanırsınız. Ancak bu hesaba dahil edilmeyen amortisman, disk yıpranması, atıl bekleyen CPU süreleri ve en önemlisi insan kaynağı maliyeti denklemi tamamen değiştiriyor. Kendi sunucunuzu kurduğunuzda, o makinenin %100 kapasiteyle çalışmadığı her saniye aslında boşa para harcıyorsunuz demektir.
SaaS Aylık Maliyet Formülü:
Maliyet = Toplam Build Süresi (dakika) x Dakika Başına Ücret + Ekstra Depolama/Ağ
Self-Hosted Aylık Maliyet Formülü:
Maliyet = Sunucu Kirası + Ağ Egress (Veri Çıkışı) + Disk Aşınması/Yedekleme + Bakım Eforu (Mühendis Saati x Saatlik Ücret)
Gerçek hayatta yaşadığım bir örnekten yola çıkayım: Build süreleri uzadığı için aceleyle self-hosted runner mimarisine geçtiğim bir projede, aylık SaaS faturası belirgin biçimde düştü. Ancak kısa süre sonra runner makinesinin diskinde biriken Docker cache’leri yüzünden disk doldu ve deploy süreçleri saatlerce tamamen durdu. O duruşun firmaya maliyeti, SaaS sistemine uzun süre ödenecek ücretten çok daha fazlaydı.
2. CPU ve Bellek Tüketim Analizi: SaaS Limitleri vs. Kendi Sunucun
SaaS sağlayıcıların sunduğu standart makineler genellikle genel amaçlı (general-purpose) paylaşımlı işlemciler kullanır. Bu durum, özellikle yoğun derleme (compilation) veya test süreçlerinde “CPU throttling” dediğimiz performans kısıtlamalarına yol açar. Kendi bare-metal sunucunuzda veya adanmış (dedicated) VPS altyapınızda ise işlemci gücünün tamamı sizin kontrolünüzdedir.
Daha önce PostgreSQL performans optimizasyonu süreçlerinde de bahsettiğim gibi, veritabanı veya yoğun girdi-çıktı (I/O) gerektiren entegrasyon testlerinde disk ve CPU hızı kritik önem taşır. SaaS ortamlarında disk I/O limitleri (IOPS) genellikle oldukça düşüktür. Kendi sunucunuzda ise NVMe disklerin gücünü sonuna kadar kullanabilirsiniz.
Aşağıdaki tabloda, standart bir SaaS runner ile $48/aylık bir self-hosted VPS runner’ın donanım ve performans metriklerini karşılaştırdım:
| Metrik | Standart SaaS Runner | Self-Hosted VPS (Adanmış) |
|---|---|---|
| vCPU | 2 Cores (Paylaşımlı) | 8 Cores (Adanmış) |
| RAM | 7 GB - 8 GB | 16 GB |
| Disk Tipi | Standart SSD (Düşük IOPS) | NVMe SSD (Yüksek IOPS) |
| Aylık Sabit Ücret | $0 (Kullandıkça Öde) | $48.00 (Sabit) |
| Eşzamanlı Build | Sınırlı (SaaS paketine göre) | Sınırsız (Donanım elverdiğince) |
Eğer eşzamanlı (parallel) build sayınız yüksekse, SaaS tarafında fatura katlanarak artar. Kendi sunucunuzda ise Docker Compose veya systemd unit’leri ile birden fazla runner’ı aynı donanım üzerinde izole ederek çalıştırabilirsiniz. Tabii burada kaynak limitlerini doğru ayarlamak şarttır. Örneğin, systemd ile koşturduğunuz bir runner için cgroup limitlerini ayarlamazsanız, bir build’in aşırı bellek tüketmesi tüm sunucuyu kilitleyebilir ve OOM (Out Of Memory) kernel paniklerine sebep olabilir.
3. Ağ Bant Genişliği (Egress Traffic) ve Depolama Maliyetleri
İşte en çok gözden kaçan ve ay sonunda muhasebe departmanından uyarı almanıza neden olan gizli canavar: Ağ Egress (veri çıkışı) maliyetleri. SaaS platformları, kendi bulut ağları dışına çıkan her gigabayt veri için ciddi ücretler talep eder. Eğer build adımlarınızda büyük Docker imajları (image) indiriliyor (pull) veya yükleniyorsa (push), veri transferi maliyetleri kısa sürede ana sunucu maliyetini aşabilir.
Örneğin, her build işleminde 1.5 GB boyutunda bir Docker imajını harici bir registry’ye push ettiğinizi düşünelim. Günde 50 build alan bir sistemde günlük 75 GB, aylık ise yaklaşık 2.2 TB veri transferi gerçekleşir. Birçok bulut sağlayıcıda GB başına $0.08 ile $0.12 arasında değişen egress ücretleri düşünüldüğünde, sadece veri transferi için aylık $180 ile $260 arasında bir fatura ile karşılaşırsınız.
Self-hosted runner kullandığınızda ise genellikle sunucu sağlayıcınız size aylık 10 TB ile 20 TB arasında ücretsiz trafik hakkı tanır. Hatta kendi lokal ağınızda (on-premise) çalışıyorsanız, bu maliyet neredeyse sıfıra iner.
# Bir self-hosted runner makinesinde günlük disk temizliği ve
# kullanılmayan Docker imajlarını temizlemek için kullandığım cron script'i:
#!/bin/bash
echo "=== Disk Temizlik Islemi Basladi: $(date) ==="
df -h /
# 24 saatten eski askıda kalan (dangling) imajları, container'ları ve volume'leri temizle
docker system prune -a --volumes --force --filter "until=24h"
echo "=== Temizlik Sonrasi Disk Durumu ==="
df -h /
Yukarıdaki script’i her gece çalışacak şekilde cron’a eklemediğim bir sunucuda, NVMe diskin kısa sürede dolduğunu ve tüm deploy pipeline’ının kilitlendiğini gördüm. SaaS sistemlerinde bu tarz disk temizleme dertleriniz olmaz; her sanal makine temiz bir imajla sıfırdan başlar ve işi bittiğinde yok edilir.
4. İşletme ve Bakım Eforu (Ops Overhead): Zaman Paradoksu
Bir sistem yöneticisi veya yazılım mimarı olarak en değerli varlığımız vaktimizdir. “Bedava” veya “ucuz” görünen self-hosted sistemlerin arkasında ciddi bir yönetim eforu (operations overhead) yatar. SaaS sistemlerinde altyapının ayakta kalması, işletim sistemi güncellemeleri, güvenlik yamaları ve ölçeklenme tamamen servis sağlayıcının sorumluluğundadır. Kendi sunucunuzda ise tüm bu yük omuzlarınızdadır.
Bir self-hosted runner sunucusunda Ubuntu LTS sürüm yükseltmesi (do-release-upgrade) yaparken Docker daemon’ın network soket yapısının değiştiğine tanık oldum. Tüm pipeline’lar bir anda çalışmaz hale geldi. Sorunu teşhis etmek (journalctl -u docker), docker-iptables çakışmasını çözmek, iptables kurallarını ve network köprülerini yeniden kurmak, ardından runner servislerini (systemd) yeniden konfigüre edip test etmek ciddi zaman aldı — ve bu kayıp tek kişiyle değil, durmuş pipeline’ı bekleyen tüm ekiple çarpılır.
Eğer ekibinizde sadece bu altyapıyla ilgilenecek adanmış bir DevOps mühendisi yoksa, self-hosted runner yönetimi yazılımcıların asıl işi olan kod geliştirmeden çalmaya başlar. Bu çalınan zamanın maliyeti, SaaS platformuna ödenecek aylık birkaç yüz dolardan her zaman daha yüksektir.
5. Güvenlik ve İzolasyon: CVE Riskleri ve Network Hardening Maliyeti
Güvenlik, self-hosted runner mimarisinin en yumuşak karnıdır. SaaS platformlarında her bir build adımı tamamen izole, geçici (ephemeral) sanal makinelerde veya korumalı container’lar içinde çalışır. Sizin build script’iniz içine sızabilecek zararlı bir kod (supply chain attack), build bittiği anda o makine yok edildiği için sisteme kalıcı olarak zarar veremez.
Ancak self-hosted runner’da durum çok farklıdır. Eğer runner’ı ana makinede doğrudan (non-containerized) çalıştırıyorsanız, build sürecinde çalışan herhangi bir script sunucunun işletim sistemine tam erişim sağlayabilir. Daha da kötüsü, aynı runner üzerinde ardışık çalışan farklı projelerin build adımları birbirlerinin environment variable’larına, SSH key’lerine veya API token’larına erişebilir.
# /etc/systemd/system/github-runner.service
# Güvenlik için runner'ı kısıtlı yetkilerle çalıştırma örneği
[Unit]
Description=GitHub Actions Runner
After=network.target
[Service]
ExecStart=/home/runner/run.sh
User=runner
Group=runner
WorkingDirectory=/home/runner
KillMode=process
Restart=always
RestartSec=5
# Basit güvenlik sıkılaştırmaları (Hardening)
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
Yukarıdaki systemd konfigürasyonunda görüldüğü gibi, runner’ı kesinlikle root yetkileriyle çalıştırmamak, ProtectSystem=full gibi parametrelerle işletim sistemi dizinlerini salt okunur (read-only) hale getirmek gerekir. Ayrıca, ağ tarafında da bu makineleri şirketin ana network segmentinden izole etmek şarttır.
Eğer bu sıkılaştırmaları (hardening) yapmazsanız, test süreçleriniz sırasında içeri sızabilecek bir CVE açığı (örneğin son dönemde can sıkan kernel modülü zafiyetleri), tüm iç ağınızı (VLAN) saldırganlara açık hale getirebilir. Bu riskleri bertaraf etmek için harcayacağınız güvenlik mühendisliği saati de doğrudan maliyet hanenize yazılır.
6. Karar Matrisi: Hangi Senaryoda Hangisini Seçmeliyiz?
Hangi yöntemin sizin için daha ekonomik olduğunu belirlemek için hazırladığım basit karar matrisine göz atabilirsiniz. Bu matris, sadece parasal maliyeti değil, operasyonel sürdürülebilirliği de hesaba katar.
Ne Zaman SaaS Tercih Edilmeli?
- Ekibinizde tam zamanlı bir sistem yöneticisi veya DevOps uzmanı yoksa.
- Aylık build süreniz 10.000 dakikanın altındaysa.
- Projeleriniz standart kütüphaneler kullanıyor ve özel donanım (GPU, yüksek RAM vb.) gerektirmiyorsa.
- Güvenlik ve izolasyon gereksinimleriniz çok katıysa ve altyapı güvenliğiyle uğraşmak istemiyorsanız.
Ne Zaman Self-Hosted Tercih Edilmeli?
- Çok büyük ve monolitik projeler derliyorsanız (örneğin C++ derlemeleri veya devasa Java paketleri) ve build süreleri SaaS üzerinde saatler sürüyorsa.
- Build süreçleriniz lokal ağınızdaki (on-premise) veritabanlarına veya özel ERP servislerine güvenli VPN bağlantısı üzerinden erişmek zorundaysa.
- Aylık build süreniz 50.000 dakikayı aşıyorsa ve SaaS faturaları binlerce doları buluyorsa.
- Kendi iç ağınızda (LAN) Docker registry veya yerel paket depoları (Nexus, Artifactory) kullanıyorsanız ve yüksek bant genişliğine ihtiyaç duyuyorsanız.
Daha önce kurumsal yazılım mimarisi tasarımlarında da gördüğüm üzere, hibrit modeller de oldukça popülerdir. Kritik olmayan, hızlı koşan testler için SaaS runner’ları kullanırken; ağır entegrasyon testleri ve deployment adımları için kendi güvenli ağımızda konumlandırdığımız kısıtlı yetkilere sahip self-hosted runner’ları tetiklemek en mantıklı trade-off’u sağlar.
Sonuç
Sonuç olarak, self-hosted runner kullanmak ilk bakışta “bedava” veya “çok ucuz” bir çözüm gibi görünse de, gizli maliyetler (disk dolmaları, ağ transfer ücretleri, güvenlik açıkları ve bakım için harcanan mühendislik saatleri) devreye girdiğinde çoğu zaman SaaS çözümlerinden daha pahalıya patlar. Altyapı kararlarını verirken sadece sunucu kirasını değil, kendi zamanınızın ve ekibinizin odak noktasının maliyetini de hesaba katmanız gerekir.
Bir sonraki yazıda, Docker imaj boyutlarını küçülterek ağ egress maliyetlerini belirgin biçimde nasıl düşürdüğümü somut Dockerfile örnekleriyle anlatacağım.