Blog DevOps

Laravel projeleri için Plesk panel deployment scripti

Plesk'te Laravel projesini tek bir bash scriptiyle yayına alıyorum: bakım modu, composer, Vite build, migration ve cache. Script ve gereken SSH ayarı burada.

Metehan KIRAN
· 6 dk okuma
Laravel projeleri için Plesk panel deployment scripti

Plesk'te bir Laravel projesini yayına almak için tek bir bash scripti yeterli: siteyi bakım moduna alır, bağımlılıkları kurar, frontend'i derler, migration'ları çalıştırır, cache'leri yeniler ve siteyi tekrar açar. Bu sitenin kendisi de böyle yayınlanıyor. Aşağıda scriptin tamamı, her satırın neden orada olduğu ve Plesk tarafında gözden kaçan bir ayar var.

Önce Plesk ayarı: SSH erişimi neden /bin/bash olmalı?

Script çalışmıyorsa ilk bakılacak yer burası. Plesk'te bir aboneliğin sistem kullanıcısı için SSH erişimi varsayılan olarak "Forbidden" gelir. Bu durumda Plesk'in Git eklentisindeki deploy komutları da dahil hiçbir shell komutu o kullanıcı adına çalışmaz.

Ayarın yeri: Websites & Domains → alan adın → Hosting Settings (yeni sürümlerde Web Hosting Access) → "Access to the server over SSH". Buradan /bin/bash seç.

Listede "/bin/bash (chrooted)" seçeneği de var ve daha güvenli göründüğü için cazip gelir. Onu seçme: chroot ortamında php, composer ve node bulunmaz, script ilk komutta "command not found" ile durur. Düz /bin/bash gerekiyor.

Bu ayar sunucuya gerçek bir shell açtığı için parola yerine SSH anahtarı kullanmanı ve parolayla girişi kapatmanı öneririm.

Scriptin tamamı

#!/bin/bash

set -euo pipefail

export PATH="/opt/plesk/node/24/bin:/opt/plesk/php/8.4/bin:$PATH"

cd "$(dirname "$(readlink -f "$0")")/.."

php artisan down --retry=15 || true

trap 'php artisan up' EXIT

composer install --no-dev --prefer-dist --no-interaction --optimize-autoloader

npm ci
npm run build

php artisan optimize:clear
php artisan filament:optimize-clear
php artisan migrate --force
php artisan storage:link || true
php artisan optimize
php artisan filament:optimize

Dosya projede scripts/deploy.sh olarak duruyor. Plesk'in Git eklentisinde "additional deployment actions" alanına bash scripts/deploy.sh yazarsan her push'tan sonra kendiliğinden çalışır. SSH ile bağlanıp elle de çalıştırabilirsin.

set -euo pipefail ne işe yarıyor?

Herhangi bir komut hata verirse scripti orada durdurur. Bu satır olmadan bash hatayı görmezden gelip devam eder; composer yarıda kalmışken migration çalıştırmak gibi sonuçlar doğar. -u tanımsız değişken kullanımını, pipefail ise pipe içindeki hataları da yakalar.

PATH satırı neden gerekli?

Plesk kendi PHP ve Node sürümlerini /opt/plesk altında tutar. Deploy sırasında açılan shell profil dosyalarını yüklemediği için php komutu ya hiç bulunmaz ya da sunucunun eski sistem PHP'sine gider. Bu satır, sitenin kullandığı sürümleri öne alır. Yoldaki sürüm numaralarını kendi sunucuna göre değiştir; hangi sürümlerin kurulu olduğunu ls /opt/plesk/php ile görebilirsin. Script composer'ın zaten PATH'te olduğunu varsayıyor.

cd satırı neden bu kadar karışık?

Script nereden çağrılırsa çağrılsın proje köküne geçmek için. readlink -f "$0" scriptin gerçek yolunu verir, dirname klasörünü alır, /.. bir üst dizine, yani proje köküne çıkar. Plesk deploy komutlarını her zaman beklediğin dizinde çalıştırmayabilir; bu satır o belirsizliği ortadan kaldırır.

Bakım modu ve trap: site kapalı kalırsa ne olur?

php artisan down --retry=15 ziyaretçilere 503 döner ve tarayıcıya 15 saniye sonra tekrar denemesini söyler. Sondaki || true ilk deploy için: vendor klasörü henüz yokken artisan çalışmaz ve script daha ilk adımda durmasın diye hata yutulur.

Asıl önemli satır trap 'php artisan up' EXIT. Script nasıl biterse bitsin, başarıyla ya da hatayla, site tekrar açılır. Bu satır olmadan npm build'de çıkan bir hata siteyi sen fark edene kadar bakım modunda bırakır.

Bunun bir bedeli var: migration yarıda hata verirse site yeni kodla ama eski veritabanı şemasıyla açılır. Ben kapalı kalmış bir site yerine bunu tercih ediyorum, çünkü hata deploy çıktısında görünüyor ve hemen müdahale edebiliyorum.

Bağımlılıklar ve build

  • composer install --no-dev: test ve geliştirme paketlerini sunucuya kurmaz. --optimize-autoloader sınıf haritasını önceden çıkarır.

  • npm ci: package-lock.json'da ne yazıyorsa onu kurar. npm install gibi sürümleri kendi kafasına göre yükseltmez.

  • npm run build: Vite ile CSS ve JS'i derler. Derlenmiş dosyaları repoya koymadığım için bu adım sunucuda çalışıyor.

Artisan komutlarının sırası neden önemli?

  1. optimize:clear önce gelir. Eski sürümün cache'lenmiş config ve route dosyaları dururken migration çalıştırmak, silinmiş bir sınıfa ya da eski bir ayara takılabilir.

  2. filament:optimize-clear aynı işi Filament'in bileşen ve ikon cache'i için yapar.

  3. migrate --force: production'da onay sorusunu atlar. Soru sorulursa script cevap bekleyerek asılı kalır.

  4. storage:link || true: link zaten varsa komut hata verir, bu yüzden hatası yutulur.

  5. optimize ve filament:optimize en sonda yeni kodun config, route, view ve bileşen cache'lerini oluşturur.

Bu script ne yapmıyor?

Kesintisiz deploy yapmıyor: composer ve build sürdüğü sürece site bakım modunda kalıyor. Kişisel bir site ya da küçük bir kurumsal proje için bu kabul edilebilir; yoğun trafikli bir uygulamada release klasörleri ve symlink değiştiren bir yapı gerekir.

Queue worker'ı da yeniden başlatmıyor. Sürekli çalışan bir worker'ın varsa sona php artisan queue:restart eklemelisin, yoksa worker eski kodla çalışmaya devam eder.

Scriptin güncel hali

Scriptin bu sitede kullandığım güncel hali GitHub'da: github.com/metehankiran/personel-website/blob/main/scripts/deploy.sh