Vercel’ın 250MB sınırını nasıl aştım: Go serverless proxy, sıkıştırılmış vendor ve birleştirilmiş PHP-FPM ikili dosyası kullanarak.
Problemin Tanımı
Problemin Tanımı
Bir Laravel + Filament uygulamasını Vercel’ın ücretsiz Hobby planında dağıtmak istedim. Hızla iki kısıtlamayla karşılaştım:
- 250MB boyut limiti — Vercel sunucusuz işlevlerinin sıkıştırılmamış bir şekilde 250MB’lık kesin bir sınırı var.
vendor/dizinim yalnızca Filament, Dompdf ve diğer paketlerle birlikte 200MB’ın üzerindeydi. - HTTP 494 hataları —
SESSION_DRIVER=cookie(stateless tek seçenek) kullanmak “Request Header Too Large” hatasına sebep oldu çünkü Filament, oturum çerezine aşırı veri yüklüyor ve Vercel’ın ~8KB başlık limitini aşıyor.
vercel-php harika bir proje, ama büyük uygulamalar için boyut problemini çözemedi.
Çözüm: Bir Go Proxy + Sıkıştırılmış Vendor
Çözüm: Bir Go Proxy + Sıkıştırılmış Vendor
vercel-laravel-go adında bir Go serverless işlevi geliştirdim; bu, PHP-FPM’i sarar ve vendor’ı ~200MB’dan ~30MB’a sıkıştırır.
Yüksek seviyede olanlar şöyle işler:
HTTP Request → Vercel → Go Handler → FastCGI → PHP-FPM → Laravel
Go işlevi, PHP yaşam döngüsünü tamamen yönetir:
- Statik bir PHP-FPM ikili dosyasını derleme sırasında (çalışma zamanında indirme gerektirmeden) paketler.
-
vendor.tar.gz‘yı soğuk başlangıçta/tmp/vendordizinine çıkarır (~30MB sıkıştırılmış, hamdan fazla 200MB). - Sembolik bağlantılar oluşturur böylece Composer’ın otomatik yükleyicisi sınıfları doğru bir şekilde çözer.
- Depolama alanını yazılabilir
/tmp/storage‘ya yönlendirir (çünkü/var/taskVercel’de salt okunur). - PHP-FPM’i bir Unix soketi üzerinde başlatır ve her isteği FastCGI üzerinden yönlendirir.
Neden Go?
Neden Go?
Vercel’ın @vercel/go çalışma zamanı, her şeyi tek bir ikili dosyaya derler. Bu bana:
- PHP-FPM ve vendor.tar.gz’yi işlev paketi içine yerleştirme fırsatı verir.
sync.Oncekullanarak bir kez soğuk başlangıç başlatması yapabilme şansı tanır.- PHP-FPM’in sıcak çağrılar arasında canlı kalmasını sağlar (konteyner tekrar kullanımı).
- FastCGI protokolünü ekstra bağımlılıklar olmadan doğrudan yönetebilme imkanı sunar.
Teknik Derinlemesine İnceleme
Teknik Derinlemesine İnceleme
Vendor Sıkıştırması
Vendor Sıkıştırması
pack.sh betiği, composer install --no-dev --optimize-autoloader komutunu çalıştırır, ardından vendor/‘ı testler ve belgeler hariç tutarak bir tar arşivine sıkıştırır:
# Dağıtmadan önce yerel olarak çalıştırın
bash scripts/pack.sh
Bu genelde 200MB+ vendor dizinini ~30MB’a düşürür.
Derleme Zamanı Hazırlığı
Derleme Zamanı Hazırlığı
Vercel’ın derleme aşamasında, vercel-prepare.sh otomatik olarak çalışır:
- Laravel kaynak dosyalarını (
app/,config/,routes/, vb.)api/laravel/dizinine kopyalar. - Statik PHP-FPM 8.4 ikilisini static-php-cli‘dan indirir.
Bunlar Go işlevi ile paketlenir — çalışma zamanında herhangi bir ağ çağrısı yapılmaz.
Soğuk Başlatma Başlatımı
Soğuk Başlatma Başlatımı
İlk istek geldiğinde, Go işleyicisi:
- PHP-FPM ikilisini
/tmp/php-fpm-bindizinine çıkarır. vendor.tar.gz‘yı/tmp/vendordizinine çıkarır./tmp/storage/altında yazılabilir dizinler oluşturur.- Sembolik bağlantılar oluşturur:
/tmp/app → /var/task/laravel/app,/tmp/config → /var/task/laravel/config, vb. - PHP giriş noktasını üretir ve
PackageManifest::$vendorPathilestoragePath‘ı geçersiz kılar. - PHP-FPM’i başlatır ve soketi bekler.
Aynı konteynırdaki sonrasındaki talepler tüm bunları atlar — PHP-FPM çalışmaya devam eder.
Neden Sembolik Bağlantılar?
Neden Sembolik Bağlantılar?
Bu en karmaşık kısımdır. Composer’ın otomatik yükleyicisi $baseDir‘yi vendor/composer/ dizininden iki üst dizin olarak hesaplar. Vendor /tmp/vendor/‘da olduğunda, uygulama sınıflarını /tmp/app/, /tmp/config/, vb. dizinlerinde arar. Ancak kaynak dosyalarımız /var/task/laravel/‘dadır. Sembolik bağlantılar bu boşluğu kapatır.
Redis ile Oturumlar
Redis ile Oturumlar
Çerez tabanlı oturumlar uygun değil (HTTP 494). Dosya oturumları da uygunsuz (her çağrıda taze bir /tmp ile karşılaşıyoruz). Çözüm: Upstash Redis (ücretsiz katman).
SESSION_DRIVER=redis
REDIS_CLIENT=predis
REDIS_URL=rediss://default:password@host:port
Başlarken
Başlarken
Bir komutla kurulum yapılır. Bunu Laravel projenizin kök dizininde çalıştırın:
curl -fsSL https://raw.githubusercontent.com/kristiansntsdev/vercel-laravel-go/main/install.sh | bash
Sonrasında:
# 1. Vendor'ı sıkıştırın
bash scripts/pack.sh
# 2. Dağıtım yapın
vercel deploy --prod
Ortam Değişkenleri
Ortam Değişkenleri
Bunları Vercel dan oluşumunda ayarlayın:
| Değişken | Değer |
|---|---|
APP_KEY | php artisan key:generate --show |
DB_* | Veritabanı kimlik bilgilerinizi girin. |
REDIS_URL | Upstash Redis URL’si. |
Diğer her şey (önbellek yolları, oturum yapılandırması, günlük kanalı) vercel.json‘da önceden yapılandırılmıştır.
GitHub Actions ile CI/CD
GitHub Actions ile CI/CD
Yükleyici ayrıca .github/workflows/deploy.yml‘yi kurar. Repo’nuzda üç gizli anahtar ekleyin:
-
VERCEL_TOKEN— vercel.com’da → Ayarlar → Tokenler -
VERCEL_ORG_ID— Vercel kullanıcı/team ID’niz -
VERCEL_PROJECT_ID— proje ayarlarınızdan alınır.
main dalına ittiğinizde otomatik olarak dağıtım yapılır.
Performans
Performans
| Metrik | Değer |
|---|---|
| Soğuk başlangıç | ~2–3 saniye |
| Sıcak istek | Hızlı (PHP-FPM canlı kalır) |
| Paket boyutu | ~50–80MB sıkıştırılmış |
| PHP versiyonu | 8.4 (statik ikili) |
Soğuk Başlangıçları Azaltma
Soğuk Başlangıçları Azaltma
Konteynerinizi sıcak tutmak için bir dış pingleyici kullanın:
Limitasyonlar
Limitasyonlar
Ticaret noktalarını göz önünde bulundurun:
- Persistan dosya sistemi yok — yönetilen bir veritabanı kullanın.
- Kuyruk işçileri yok — Railway, Fly.io veya benzerlerinde çalıştırın.
- CRON yok — bir dış planlayıcı veya Vercel Pro cron kullanın.
- 60s maksimum istekte süre Hobby planında.
- Statik IP yok — sunucusuz dostu bir veritabanı kullanın (Neon, Supabase, PlanetScale).
Sonuç
Sonuç
Ağır bir Laravel uygulamasını Vercel’a dağıtmakta zorlanıyorsanız, vercel-laravel-go‘yu denemeniz faydalı olabilir. Laravel 11 ve 12 ile uyumlu çalışır, Filament uygulamalarını zahmetsizce yönetir ve Vercel’ın ücretsiz katmanında dağıtılır.
Ana fikir: vendor’ı sıkıştırın, PHP-FPM’i birleştirin ve Go’nun altyapıyı yönetmesini sağlayın.
Yardımcı olursa repoyu yıldızlayın: github.com/kristiansntsdev/vercel-laravel-go
Kaynak: Orijinal Makale


