Laravel 9 dk okuma

Laravel VDS Kurulumu: Ubuntu 24.04, Nginx, PHP-FPM, SSL, Queue ve Cron

Laravel'i VDS sunucuda yayına alma: Ubuntu 24.04'te Nginx, PHP 8.3 FPM, MariaDB ve Composer kurulumu, dosya izinleri, .env güvenliği, Nginx yapılandırması, Certbot SSL, Supervisor ile queue:work, cron ile schedule:run ve dağıtım sırası.

Laravel VDS Kurulumu: Ubuntu 24.04, Nginx, PHP-FPM, SSL, Queue ve Cron
AnkSOFT
Yayıncı

Laravel uygulamanızı kendi sunucunuzda çalıştırmak; kuyruk işçilerini kesintisiz açık tutmanızı, PHP ayarlarını projeye göre yapmanızı ve Composer'ı doğrudan sunucuda kullanmanızı sağlar. Bu rehberde Laravel VDS kurulumunu sıfırdan bir Ubuntu 24.04 sunucuda adım adım anlatıyoruz: Nginx, PHP 8.3 FPM, MariaDB, Composer, proje dosyaları, dosya izinleri, .env güvenliği, ücretsiz SSL, Supervisor ile queue:work ve cron ile schedule:run. Sonunda her güncellemede uygulayacağınız kısa bir dağıtım sırası da var.

Laravel tarafındaki Artisan çıktıları gerçek bir Laravel 13.39 projesinden alınmıştır. Nginx ve Supervisor yapılandırma görselleri Laravel'in resmi belgelerindeki örneklere dayanan temsilî çizimlerdir; kendi alan adınız ve klasör yolunuzla uyarlayın.


Başlamadan Önce

  • Sunucu: Ubuntu 24.04 LTS kurulu bir VDS. Ubuntu 24.04'ün kendi depolarındaki PHP sürümü 8.3'tür; Laravel 13'ün istediği en düşük sürüm de budur, ek depo eklemeden kurulur. Debian 13 kullanıyorsanız depodaki sürüm PHP 8.4'tür ve paket adları php8.4-... olur.
  • Alan adı: alanadiniz.com ve www için A kaydı sunucunuzun IP adresini göstermeli. Kayıtların nasıl girileceği DNS kayıtları rehberimizde anlatılıyor.
  • Sunucu güvenliği: Root ile parola girişini kapatmak, SSH anahtarı ve güvenlik duvarı için önce Ubuntu sunucu güvenliği rehberimizi uygulayın. Bu rehberdeki komutlar sudo yetkili, root olmayan bir kullanıcıyla (örnekte deploy) çalıştırılır.
  • Portlar: 80 ve 443 portları hem sunucu içindeki güvenlik duvarında (UFW) hem de VDS panelindeki güvenlik duvarında açık olmalı.

Nginx, PHP ve MariaDB kurulumunu genel olarak LEMP kurulumu rehberimizde ayrıntılı anlattık. Bu yazı aynı yığını Laravel'e özgü ayarlarla kurar.


Adım 1: Nginx, PHP 8.3 ve Gerekli Eklentileri Kurun

sudo apt update
sudo apt install -y nginx mariadb-server unzip git supervisor \
  php8.3-fpm php8.3-cli php8.3-mysql php8.3-mbstring php8.3-xml \
  php8.3-curl php8.3-zip php8.3-bcmath php8.3-intl php8.3-gd

Bu paketler Laravel'in istediği eklentilerin hepsini getirir: Ctype, Fileinfo, Tokenizer ve PDO php8.3-common ile, DOM ve XML php8.3-xml ile gelir. Kontrol etmek için:

php -v
php -m | grep -E 'mbstring|xml|curl|pdo_mysql|bcmath|intl|zip'

Ubuntu 24.04'te Nginx, MariaDB, Supervisor ve PHP 8.3 FPM eklentilerinin kurulumu ve php -m kontrolü


Adım 2: Composer'ı Resmi Betikle Kurun

Composer'ı imzası doğrulanmış resmi kurulum betiğiyle kurun:

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === trim(file_get_contents('https://composer.github.io/installer.sig'))) { echo 'Installer verified'.PHP_EOL; } else { echo 'Installer corrupt'.PHP_EOL; unlink('composer-setup.php'); exit(1); }"
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
php -r "unlink('composer-setup.php');"
composer --version

"Installer verified" yazmadıysa dosya bozuk veya değiştirilmiştir; kurulumu sürdürmeyin.

Arayüz dosyalarını (Vite) sunucuda derleyecekseniz Node.js 22 LTS veya üstünü de kurun. Laravel 13 iskeletindeki Vite 8, Ubuntu 24.04 deposundaki Node.js 18 ile çalışmaz. Node kurmak istemezseniz npm run build komutunu bilgisayarınızda çalıştırıp public/build klasörünü sunucuya yükleyebilirsiniz.


Adım 3: Veritabanı ve Kullanıcı Oluşturun

sudo mariadb
CREATE DATABASE ornek CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ornek'@'localhost' IDENTIFIED BY 'guclu-bir-parola';
GRANT ALL PRIVILEGES ON ornek.* TO 'ornek'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Kullanıcıyı '%' yerine 'localhost' ile tanımlayın; veritabanı dışarıdan bağlantı kabul etmesin. MariaDB'nin 3306 portunu güvenlik duvarında açmayın.


Adım 4: Projeyi Sunucuya Alın

Projeyi /var/www/ornek klasörüne Git ile çekin (ya da SFTP ile yükleyin):

sudo mkdir -p /var/www/ornek
sudo chown deploy:www-data /var/www/ornek
cd /var/www/ornek
git clone https://github.com/kullanici/ornek-proje.git .
composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate

Özel bir depo kullanıyorsanız sunucuda bir deploy anahtarı (yalnızca okuma yetkili SSH anahtarı) tanımlayın; Git hesabınızın parolasını sunucuya yazmayın.

.env dosyasını yayına göre düzenleyin

APP_ENV=production
APP_DEBUG=false
APP_URL=https://alanadiniz.com

LOG_CHANNEL=daily
LOG_LEVEL=error

DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ornek
DB_USERNAME=ornek
DB_PASSWORD=guclu-bir-parola

QUEUE_CONNECTION=database
CACHE_STORE=database
SESSION_DRIVER=database
SESSION_SECURE_COOKIE=true
  • APP_DEBUG=false zorunludur. Laravel belgelerinin uyarısıyla: yayında true bırakmak, hassas ayar değerlerini son kullanıcıya gösterme riski taşır.
  • APP_KEY key:generate ile üretildi. Yayına aldıktan sonra değiştirmeyin; değişirse oturumlar düşer ve şifrelenmiş veriler okunamaz.
  • SESSION_SECURE_COOKIE=true, oturum çerezinin yalnızca HTTPS üzerinden gönderilmesini sağlar. SSL kurulduktan sonra etkinleştirin.

Adım 5: Dosya Sahipliği ve İzinler

Laravel yalnızca iki klasöre yazar: storage ve bootstrap/cache. Kodun geri kalanı web sunucusu tarafından yalnızca okunmalıdır. PHP-FPM Ubuntu'da www-data kullanıcısıyla çalışır:

cd /var/www/ornek
sudo chown -R deploy:www-data .
sudo find . -type f -exec chmod 644 {} \;
sudo find . -type d -exec chmod 755 {} \;
sudo chmod -R ug+rwX storage bootstrap/cache
sudo chmod 640 .env

Laravel dosya izinleri: kod 644/755, storage ve bootstrap/cache grup yazılabilir, .env 640

  • Dosyalar deploy kullanıcısına, grup www-data'ya aittir. PHP kodu değiştiremez, yalnızca okur.
  • storage ve bootstrap/cache grup için yazılabilirdir.
  • .env 640: sahibi okuyup yazar, www-data yalnızca okur, diğer kullanıcılar hiç göremez.
  • 777 vermeyin. "Permission denied" hatasını 777 ile geçiştirmek, sunucudaki her kullanıcıya ve ele geçirilmiş her sürece kodunuzu değiştirme yetkisi verir.

Önemli: Laravel'e yazan Artisan komutlarını (migrate, optimize, queue:work) web sunucusunun kullanıcısıyla çalıştırın: sudo -u www-data php artisan .... deploy kullanıcısıyla çalışan bir komut storage/logs/laravel.log dosyasını ilk kez oluşturursa dosya deploy'a ait ve 644 olur; sonra web istekleri günlüğe yazamaz ve site "Permission denied" ile 500 hatası verir.


Adım 6: Nginx Sunucu Bloğu

/etc/nginx/sites-available/ornek dosyasını oluşturun. Aşağıdaki yapılandırma Laravel'in resmi dağıtım belgesindeki örnektir; tek fark root satırının projenin public klasörünü göstermesidir:

server {
    listen 80;
    listen [::]:80;
    server_name alanadiniz.com www.alanadiniz.com;
    root /var/www/ornek/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;
    charset utf-8;
    client_max_body_size 20M;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_buffer_size 32k;
        fastcgi_buffers 8 32k;
        fastcgi_busy_buffers_size 64k;
        fastcgi_hide_header X-Powered-By;
    }

    location ~ \.php$ {
        return 404;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Laravel için Nginx sunucu bloğu: root public klasörü, try_files, PHP-FPM soketi ve gizli dosya engeli

Bu yapılandırmanın güvenlik açısından önemli üç satırı vardır:

  • root /var/www/ornek/public; web'e yalnızca public klasörünü açar; .env, storage ve vendor dışarıdan istenemez.
  • location ~ \.php$ { return 404; } yalnızca index.php'nin çalışmasına izin verir; public içine bir şekilde bırakılmış başka bir PHP dosyası çalıştırılamaz.
  • location ~ /\.(?!well-known).* nokta ile başlayan dosyaları (.env, .git) engeller, yalnızca SSL doğrulaması için gereken .well-known klasörünü açık bırakır.

Etkinleştirip test edin:

sudo ln -s /etc/nginx/sites-available/ornek /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

Adım 7: Ücretsiz SSL Sertifikası

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d alanadiniz.com -d www.alanadiniz.com

Certbot sertifikayı alır, Nginx yapılandırmasına 443 bloğunu ekler ve HTTP'den HTTPS'e yönlendirmeyi kurar. Sertifika 90 günde bir kendiliğinden yenilenir; yenilemeyi sudo certbot renew --dry-run ile deneyebilirsiniz. Sonra .env'de APP_URL'in https:// ile başladığından emin olun.


Adım 8: Migration, Önbellek ve Dosya Bağlantısı

cd /var/www/ornek
sudo -u www-data php artisan migrate --force
sudo -u www-data php artisan storage:link
sudo -u www-data php artisan optimize
  • migrate --force: Yayın ortamında onay sormadan tabloları kurar.
  • storage:link: public/storage adresinden yüklenen dosyalara erişim sağlar. VDS'te symlink kapalı olmadığı için doğrudan çalışır.
  • optimize: Ayar, olay, rota ve görünümleri önbelleğe alır. Önemli: önbellek açıkken .env dosyası okunmaz; .env'i her değiştirdiğinizde php artisan optimize komutunu yeniden çalıştırın. Kodunuzda env() çağrısını yalnızca config/ dosyalarında kullanın, aksi halde önbellekten sonra null döner.

php artisan optimize çıktısı: config, events, routes ve views önbelleğe alındı

Tarayıcıda https://alanadiniz.com/up adresini açın; Laravel'in sağlık denetimi uygulama hatasız açılıyorsa 200 döner.


Adım 9: Kuyruk İşçisi için Supervisor

QUEUE_CONNECTION=database ile kuyruğa atılan işler (e-posta gönderme, rapor hazırlama, görsel küçültme) ancak bir queue:work süreci çalışıyorsa işlenir. Bu süreç terminali kapattığınızda durmamalı, çökerse yeniden başlamalıdır. Bunu Supervisor yapar.

/etc/supervisor/conf.d/ornek-worker.conf dosyasını oluşturun:

[program:ornek-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/ornek/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/ornek/storage/logs/worker.log
stopwaitsecs=3600

Supervisor ornek-worker.conf yapılandırması ve supervisorctl status çıktısı

  • numprocs=2: Aynı anda iki işçi çalışır. VDS'inizin çekirdek sayısına ve iş yüküne göre ayarlayın.
  • --max-time=3600: İşçi bir saat sonra kendini kapatır, Supervisor yenisini başlatır; zamanla biriken bellek boşalır.
  • stopwaitsecs: En uzun işinizden uzun olmalı; yoksa Supervisor işi yarıda keser.
  • user=www-data: İşçinin oluşturduğu günlük ve önbellek dosyaları web sunucusuyla aynı kullanıcıya ait olur.

Supervisor'a yeni dosyayı okutup başlatın:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start "ornek-worker:*"
sudo supervisorctl status

İşçiler çalışırken işlenen işler şöyle görünür:

queue:work çıktısı: RaporHazirla işi RUNNING ve DONE

Kuyruk işçileri uzun yaşayan süreçlerdir ve kodunuz değiştiğinde bunu fark etmezler. Her dağıtımdan sonra php artisan queue:restart çalıştırın; işçiler ellerindeki işi bitirip kapanır, Supervisor yeni kodla yeniden başlatır.


Adım 10: Zamanlanmış Görevler için Cron

Laravel zamanlayıcısı için sunucuya tek bir cron satırı eklenir. Satırı www-data kullanıcısının crontab'ına yazın:

sudo crontab -u www-data -e
* * * * * cd /var/www/ornek && php artisan schedule:run >> /dev/null 2>&1

Görevler routes/console.php dosyasında tanımlanır. Hangi görevin ne zaman çalışacağını görmek için:

php artisan schedule:list

php artisan schedule:list çıktısı: zamanlanmış iş, Artisan komutu ve kapanış görevinin sonraki çalışma zamanları

VDS'te proc_open kapalı olmadığı için Schedule::command(...) ve ->runInBackground() dahil zamanlayıcının bütün özellikleri kullanılabilir. Birden fazla sunucunuz varsa aynı görevin tek sunucuda çalışması için ->onOneServer() ekleyin (önbellek sürücüsü database veya redis olmalı).


Adım 11: Her Güncellemede Uygulanacak Dağıtım Sırası

Kodunuzu güncellerken aynı adımları aynı sırayla çalıştırmak, yarım kalmış güncellemeleri ve "dün çalışıyordu" sorunlarını önler:

cd /var/www/ornek
sudo -u www-data php artisan down --retry=60
git pull origin main
composer install --no-dev --optimize-autoloader
sudo -u www-data php artisan migrate --force
npm ci && npm run build
sudo -u www-data php artisan optimize
sudo -u www-data php artisan queue:restart
sudo systemctl reload php8.3-fpm
sudo -u www-data php artisan up

Laravel dağıtım sırası: bakım modu, git pull, composer install, migrate, build, optimize, queue:restart, PHP-FPM reload, yayına açma

  • down --retry=60: Ziyaretçilere bakım sayfası gösterir; tarayıcılara 60 saniye sonra tekrar denemelerini söyler.
  • systemctl reload php8.3-fpm: OPcache'teki eski PHP kodunu bırakır; kesinti yaratmaz.
  • Migration öncesinde veritabanı yedeği alın: mariadb-dump -u ornek -p --single-transaction ornek > ornek-$(date +%F).sql.

Performans ve Güvenlik İçin Ek Öneriler

  • OPcache açık olmalı. Ubuntu'nun PHP-FPM paketinde varsayılan olarak açıktır; php -i | grep opcache.enable ile kontrol edin.
  • Redis: Yoğun projelerde önbellek, oturum ve kuyruk için redis-server ve php8.3-redis kurup .env'de CACHE_STORE=redis, QUEUE_CONNECTION=redis kullanabilirsiniz. Redis'i yalnızca 127.0.0.1 üzerinde dinletin.
  • Günlükler: LOG_CHANNEL=daily günlükleri gün gün böler ve eski dosyaları siler; disk dolmaz.
  • Güncellemeler: PHP, Nginx ve Laravel'in güvenlik güncellemelerini düzenli uygulayın. Kritik açıklar için PHP ve Next.js güvenlik güncellemesi rehberimize bakabilirsiniz.
  • Docker tercih ederseniz: Aynı yığını konteynerlerle kurmak için Docker kurulumu rehberimiz iyi bir başlangıçtır.

En Sık Hatalar

  1. 502 Bad Gateway. Nginx PHP-FPM soketine ulaşamıyordur. fastcgi_pass satırındaki sürüm (php8.3-fpm.sock) kurulu PHP ile aynı mı, sudo systemctl status php8.3-fpm çalışıyor mu kontrol edin.
  2. Ana sayfa açılıyor, diğer adresler Nginx 404 veriyor. try_files $uri $uri/ /index.php?$query_string; satırı eksiktir.
  3. "Permission denied" ile 500 hatası. storage veya bootstrap/cache yazılamıyordur ya da günlük dosyası başka kullanıcıya aittir. Adım 5'teki komutları yeniden çalıştırın.
  4. .env'i değiştirdim ama değişmedi. Ayar önbelleği açıktır; php artisan optimize çalıştırın.
  5. Kuyruktaki işler işlenmiyor. sudo supervisorctl status ile işçilerin RUNNING olduğunu, storage/logs/worker.log dosyasını kontrol edin. Kod değiştiyse queue:restart unutulmuştur.
  6. Zamanlanmış görev çalışmıyor. Cron satırının www-data crontab'ında olduğunu ve yolun doğru olduğunu kontrol edin: sudo crontab -u www-data -l.

Daha fazla hata ve çözüm için Laravel 500 hatası rehberimize bakın.


Özet

  1. Ubuntu 24.04'te Nginx, PHP 8.3 FPM, MariaDB, Supervisor ve Laravel'in istediği PHP eklentilerini kurun; Composer'ı imzası doğrulanmış resmi betikle yükleyin.
  2. Projeyi /var/www/ornek klasörüne alın, composer install --no-dev --optimize-autoloader çalıştırın, .env'de APP_ENV=production ve APP_DEBUG=false yapın.
  3. Dosyaları deploy:www-data sahipliğine verin, yalnızca storage ve bootstrap/cache yazılabilir olsun, .env 640 olsun.
  4. Nginx'in root satırı public klasörünü göstersin, Certbot ile SSL kurun.
  5. Kuyruk için Supervisor, zamanlayıcı için www-data crontab'ında her dakika schedule:run kullanın.
  6. Her güncellemede aynı dağıtım sırasını uygulayın ve sonunda queue:restart çalıştırın.

Laravel uygulamanız için Türkiye lokasyonlu, Ubuntu 24.04 ve Debian 13 kurulabilen VDS sunucu paketlerimizi inceleyebilirsiniz. Sunucu yönetimiyle uğraşmak istemeyen küçük projeler için cPanel'li web hosting paketlerimizde Laravel'i SSH olmadan nasıl çalıştıracağınızı ayrıca anlattık. Laravel'e yeni başlıyorsanız Laravel nedir ve nasıl kurulur rehberimizle başlayın.


Kaynaklar

Sıkça Sorulan Sorular

Laravel için Nginx yapılandırması nasıl olmalı?

Sunucu bloğunun root satırı projenin public klasörünü göstermeli, location / içinde try_files $uri $uri/ /index.php?$query_string; bulunmalı ve yalnızca index.php PHP-FPM'e gönderilmelidir. Laravel'in resmi örneği ayrıca diğer .php dosyalarına 404 döner ve .well-known dışındaki nokta ile başlayan dosyaları engeller.

Laravel storage ve bootstrap/cache izinleri ne olmalı?

Dosyalar deploy kullanıcısına ve www-data grubuna ait olmalı; dosyalar 644, klasörler 755 olmalı. Yalnızca storage ve bootstrap/cache grup için yazılabilir olmalı (chmod -R ug+rwX), .env 640 olmalı. 777 izni verilmemelidir.

Laravel queue:work sürekli nasıl çalıştırılır?

Supervisor ile çalıştırılır. /etc/supervisor/conf.d altına command=php /var/www/ornek/artisan queue:work --sleep=3 --tries=3 --max-time=3600 satırını içeren bir program tanımı yazın, user=www-data ve autorestart=true verin, ardından supervisorctl reread, update ve start komutlarını çalıştırın. Her dağıtımdan sonra php artisan queue:restart çalıştırın.

Laravel schedule:run cron satırı nedir?

Sunucuya tek bir cron satırı eklenir: * * * * * cd /var/www/ornek && php artisan schedule:run >> /dev/null 2>&1. Satırı web sunucusunun kullanıcısı olan www-data'nın crontab'ına sudo crontab -u www-data -e ile ekleyin. Görevler routes/console.php dosyasında tanımlanır, php artisan schedule:list ile listelenir.

Laravel'de .env değiştirdim ama değişiklik yansımıyor, neden?

php artisan optimize veya config:cache çalıştırıldığında ayarlar önbelleğe alınır ve .env dosyası artık okunmaz. .env'i her değiştirdiğinizde php artisan optimize komutunu yeniden çalıştırın. Kodunuzda env() fonksiyonunu yalnızca config klasöründeki dosyalarda kullanın.

Laravel için hangi VDS işletim sistemi seçilmeli?

Ubuntu 24.04 LTS iyi bir başlangıçtır; depodaki PHP 8.3, Laravel 13'ün istediği en düşük sürümdür ve ek depo gerektirmez. Debian 13 kullanırsanız depoda PHP 8.4 gelir. Arayüz derlemesi için Vite 8'in istediği Node.js 20.19 veya 22.12 ve üzeri ayrıca kurulmalıdır.

TR| EN