Laravel Production Deploy Rehberi İlk Felaket Deploy’dan 5 Dakikalık Sürece

Konu İçeriği
Migration Hatası
Sebep: local’de çalışan migration production’da çalışmıyor çünkü database yapısı farklı olabilir. Çözüm: her migration’ı local’de test ettikten sonra production’da --pretend flag’i ile önce simüle edin: php artisan migrate --pretend. Bu komut SQL’i çalıştırmadan gösterir.
Beyaz Ekran (Blank Page)
Sebep: PHP error display kapalı ve critical bir hata var. Çözüm: storage/logs/laravel.log ve /var/log/nginx/error.log dosyalarını kontrol edin. Biri mutlaka gerçek hatayı gösteriyor.
Post-Deploy Kontrol Listesi
Deploy sonrası mutlaka kontrol ettiğim şeyler:
- Ana sayfa açılıyor mu? Basit ama ilk kontrol bu olmalı.
- Login çalışıyor mu? Database bağlantısı ve session sorunu varsa burada belli olur.
- API endpoint’leri respond veriyor mu? Postman veya curl ile test edin.
- Cron job çalışıyor mu?
* * * * * cd /var/www/proje && php artisan schedule:run >> /dev/null 2>&1 - Queue worker çalışıyor mu? Supervisor ile daemon olarak çalıştırın.
- Log dosyası temiz mi? Deploy sonrası log boş olmalı. Hemen hata yazıyorsa bir şey yanlış.
- SSL düzgün çalışıyor mu? HTTPS ile girin, mixed content uyarısı yok mu kontrol edin.
Supervisor ile Queue Worker
Laravel’de e-posta gönderme, dosya işleme gibi uzun süreli işlemleri queue’ya atıyorsanız, queue worker’ın sürekli çalışması gerekiyor. Terminalde manuel php artisan queue:work çalıştırırsanız terminal kapandığında worker da durur. Bunun yerine Supervisor kurun:
apt install supervisor
/etc/supervisor/conf.d/laravel-worker.conf dosyası oluşturun:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/proje-adi/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=2
user=www-data
Supervisor worker çökerse otomatik yeniden başlatır. numprocs=2 ile iki paralel worker çalıştırıyorsunuz. E-posta kuyruğu birikecek kadar uzun değilse 2 yeterli. Ben bu ayarı yapmadan önce e-postalar saatlerce kuyrukta bekliyordu.
Sonuç
Laravel production deploy korkutucu değil sadece sistematik bir süreç. Sunucu hazırlığı, Git ile kod taşıma, Composer, environment ayarları, migration, dosya izinleri, cache. Her adımı sırasıyla ve dikkatle yaparsanız sorunsuz bir deploy yaşarsınız.
Ben o ilk felaket deploy’dan bu yana yüzlerce deploy yaptım ve artık 5 dakikada tamamlıyorum. Ama hâlâ kontrol listemi kullanıyorum çünkü insan unutur. Kontrol listesi unutmaz. Otomasyon kurmak daha da iyi otomasyon hiç unutmaz.
İlk Laravel projemi production’a alırken yaşadığım şey tam bir felaketti. FTP ile dosyaları yükledim, database’i import ettim, .env dosyasını unuttum, site açılmadı. Sonra hatayı buldum, düzelttim, tekrar yükledim bu kez de migration çalışmamıştı. Toplam 6 saatimi almıştı ve sonunda site ancak yarım çalışıyordu. O günden beri onlarca Laravel projesi deploy ettim ve artık süreç 5 dakikamı alıyor. Aradaki fark mı? Sistematik bir yöntem ve her adımda kontrol.
Production Deploy Neden Korkutucu?
Çünkü local’de çalışan bir şey production’da çalışmayabilir. Ortam farklı, ayarlar farklı, PHP versiyonu farklı, extension’lar eksik olabilir. Benim ilk deploy’umda sorun PHP versiyonuydu local’de PHP 8.2, sunucuda PHP 7.4. Laravel 10, PHP 8.1 altında çalışmaz. Bunu deploy sonrası öğrendim ve “Internal Server Error” ile boğuşmaya başladım.
Production deploy’u korkutucu olmaktan çıkaran şey, adımları bilmek ve kontrol listesi kullanmak. İşte kendi kontrol listemi baştan sona paylaşıyorum.
Deploy Öncesi Sunucu Hazırlığı
Koda dokunmadan önce sunucunun hazır olduğundan emin olmalısınız:
- PHP versiyonu: Laravel 11 için minimum PHP 8.2.
php -vile kontrol edin. Eski versiyonsa, remi repository’sinden güncel PHP’yi kurun. - PHP extension’ları: BCMath, Ctype, cURL, DOM, Fileinfo, JSON, Mbstring, OpenSSL, PDO, Tokenizer, XML hepsi kurulu olmalı.
php -mile listeyi kontrol edin. - Composer: Kurulu ve güncel olmalı.
composer --versionile kontrol edin. - Web server: Nginx + PHP-FPM öneriyorum. Apache da çalışır ama Nginx Laravel ile daha iyi performans veriyor.
- Database: MySQL 8+ veya PostgreSQL 14+. Kullanıcı ve database oluşturulmuş olmalı.
- SSL: Let’s Encrypt ile ücretsiz SSL kurun. HTTPS’siz site 2026’da kabul edilemez.
Ben bu adımları bir kez script’leyip kaydettim. Yeni sunucu kurulumunda script’i çalıştırıyorum ve 10 dakikada hazır. Her seferinde manuel yapmak riskli bir extension’ı unutursanız saatlerce hata ayıklarsınız.
Nginx Konfigürasyonu Laravel İçin Kritik
Laravel’in çalışması için Nginx konfigürasyonunda document root’u public klasörüne yönlendirmeniz gerekiyor. Bu çok yaygın bir hata root’u proje dizinine ayarlayınca site açılmaz. Doğru ayar:
root /var/www/proje-adi/public;
Ve index.php’yi rewrite kuralıyla yakalamalısınız:
location / { try_files $uri $uri/ /index.php?$query_string; }
Bu iki satır olmadan Laravel route’ları çalışmaz. Ben ilk kurulumda bunu bilmiyordum ve her route 404 veriyordu. İki saatimi bu iki satırı bulmaya harcadım.

Adım Adım Deploy Süreci
1. Kodu Sunucuya Taşıyın
FTP ile dosya taşımak 2010’larda kaldı. Doğru yöntem Git kullanmak:
cd /var/www
git clone https://github.com/kullanici/proje.git proje-adi
Ya da mevcut bir proje güncellenecekse:
cd /var/www/proje-adi
git pull origin main
Git ile deploy’un avantajı: rollback kolay. Bir şey bozuksa git checkout HEAD~1 ile bir önceki versiyona dönebilirsiniz. FTP’de bu mümkün değil hangi dosyayı değiştirdiğinizi hatırlamanız lazım.
2. Composer Dependencies
Vendor klasörünü GitHub’a yüklemeyin bunu her seferinde sunucuda yükleyin:
composer install --optimize-autoloader --no-dev
--no-dev flag’i development araçlarını (PHPUnit, Faker vb.) yüklemez. Production’da bunlara gerek yok ve sadece alan işgal eder. --optimize-autoloader ise class loading’i hızlandırır.
3. Environment Ayarları
.env dosyası production’a özel olmalı. Local’deki .env’yi kesinlikle kullanmayın database bilgileri, API key’leri, debug modu hepsi yanlış olur. Template olarak .env.example’ı kopyalayın ve doldurun:
cp .env.example .env
nano .env
Kritik ayarlar:
APP_ENV=productionAPP_DEBUG=falsetrue bırakırsanız hata mesajları kullanıcıya gösterilir, güvenlik riskiAPP_KEY=boş bırakın, sonraki adımda generate edeceğizDB_*production database bilgileri
4. Application Key ve Cache
php artisan key:generate
php artisan config:cache
php artisan route:cache
php artisan view:cache
Bu dört komut sırasıyla: encryption key oluşturur, config dosyalarını cache’ler, route listesini cache’ler ve view’ları compile eder. Her biri performansı ciddi artırır. Ben route cache sonrası sayfa yüklenme süresinin 40 ms azaldığını gördüm.
5. Database Migration
php artisan migrate --force
--force flag’i production ortamında migration çalıştırmak için gerekli Laravel production’da yanlışlıkla migration çalıştırılmasını engeller. Seed de gerekiyorsa:
php artisan db:seed --force
Migration öncesi yedek almayı unutmayın. Ben bir kez migration’ı yanlış yazdım ve tüm user tablosunu drop ettim. Yedek yoktu, kullanıcıların hepsini yeniden kayıt olmaya mecbur bıraktım. O günden beri migration öncesi mysqldump çalıştırıyorum.

6. Dosya İzinleri
Laravel’in yazma izni olan klasörlere ihtiyacı var. Yanlış izinler “500 Internal Server Error” döndürür:
chown -R www-data:www-data /var/www/proje-adi
chmod -R 775 storage bootstrap/cache
Storage klasörü log, cache ve compiled dosyalar için kullanılıyor. Bu klasörlere yazma izni yoksa Laravel sessizce ölür hata log’u bile yazamaz. Ben bu hatayı iki kez yaptım ve her seferinde “neden çalışmıyor” diye saatlerce uğraştım.
Deploy Otomasyonu Zero-Downtime
Manuel deploy küçük projelerde çalışır ama ciddi projelerde otomasyon şart. Benim kullandığım iki yöntem:
Envoyer (Ücretli)
Laravel ekibinin sunduğu deploy servisi. Git push yapın, Envoyer otomatik sunucuya deploy eder. Zero-downtime yani deploy sırasında site kesintiye uğramaz. Kullanıcılar hiçbir şey fark etmez. Aylık 10 dolar ve her kuruşuna değer. Ben müşteri projelerinde bunu kullanıyorum.
Deployer (Ücretsiz)
Açık kaynaklı PHP deploy aracı. Bir deploy.php dosyası yazıyorsunuz ve dep deploy komutuyla her şeyi otomatik yapıyor. Zero-downtime destekli, rollback özellikli. Kendi sunucunuzda kuruyorsunuz, aylık ücret yok. Ben kişisel projelerde Deployer kullanıyorum.
Temel bir deploy.php yapılandırması 20-30 satır ve bir kez yazıyorsunuz. Sonrasında her deploy tek komutla. Otomasyon kurmak 1-2 saat sürer ama sonrasında her deploy 30 saniye sürer. Matematik basit.
Yaygın Deploy Hataları ve Çözümleri
Yıllar içinde karşılaştığım ve her seferinde saatlerimi yiyen hatalar:
“500 Internal Server Error”
Sebepleri: storage/bootstrap/cache izinleri yanlış, .env dosyası yok, APP_KEY boş. Çözüm: storage/logs/laravel.log dosyasını okuyun. Laravel her hatayı loglar ve gerçek sebep orada yazar.
“Class not found” Hatası
Sebep: composer dump-autoload çalıştırılmamış. Çözüm: composer dump-autoload -o. Bu komut class map’i yeniden oluşturur. Yeni bir class eklediyseniz ve çalışmıyorsa, önce bunu deneyin.
Migration Hatası
Sebep: local’de çalışan migration production’da çalışmıyor çünkü database yapısı farklı olabilir. Çözüm: her migration’ı local’de test ettikten sonra production’da --pretend flag’i ile önce simüle edin: php artisan migrate --pretend. Bu komut SQL’i çalıştırmadan gösterir.
Beyaz Ekran (Blank Page)
Sebep: PHP error display kapalı ve critical bir hata var. Çözüm: storage/logs/laravel.log ve /var/log/nginx/error.log dosyalarını kontrol edin. Biri mutlaka gerçek hatayı gösteriyor.
Post-Deploy Kontrol Listesi
Deploy sonrası mutlaka kontrol ettiğim şeyler:
- Ana sayfa açılıyor mu? Basit ama ilk kontrol bu olmalı.
- Login çalışıyor mu? Database bağlantısı ve session sorunu varsa burada belli olur.
- API endpoint’leri respond veriyor mu? Postman veya curl ile test edin.
- Cron job çalışıyor mu?
* * * * * cd /var/www/proje && php artisan schedule:run >> /dev/null 2>&1 - Queue worker çalışıyor mu? Supervisor ile daemon olarak çalıştırın.
- Log dosyası temiz mi? Deploy sonrası log boş olmalı. Hemen hata yazıyorsa bir şey yanlış.
- SSL düzgün çalışıyor mu? HTTPS ile girin, mixed content uyarısı yok mu kontrol edin.
Supervisor ile Queue Worker
Laravel’de e-posta gönderme, dosya işleme gibi uzun süreli işlemleri queue’ya atıyorsanız, queue worker’ın sürekli çalışması gerekiyor. Terminalde manuel php artisan queue:work çalıştırırsanız terminal kapandığında worker da durur. Bunun yerine Supervisor kurun:
apt install supervisor
/etc/supervisor/conf.d/laravel-worker.conf dosyası oluşturun:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/proje-adi/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
numprocs=2
user=www-data
Supervisor worker çökerse otomatik yeniden başlatır. numprocs=2 ile iki paralel worker çalıştırıyorsunuz. E-posta kuyruğu birikecek kadar uzun değilse 2 yeterli. Ben bu ayarı yapmadan önce e-postalar saatlerce kuyrukta bekliyordu.
Sonuç
Laravel production deploy korkutucu değil sadece sistematik bir süreç. Sunucu hazırlığı, Git ile kod taşıma, Composer, environment ayarları, migration, dosya izinleri, cache. Her adımı sırasıyla ve dikkatle yaparsanız sorunsuz bir deploy yaşarsınız.
Ben o ilk felaket deploy’dan bu yana yüzlerce deploy yaptım ve artık 5 dakikada tamamlıyorum. Ama hâlâ kontrol listemi kullanıyorum çünkü insan unutur. Kontrol listesi unutmaz. Otomasyon kurmak daha da iyi otomasyon hiç unutmaz.


