Orijinal yayın hafiz.dev‘da
Spatie, 30 Mart’ta Scotty’yi duyurdu. Bu, Laravel Envoy’un yaptığı gibi: uzak sunucularda deploy script’lerini çalıştıran yeni bir SSH task runner. Ancak, Blade template’leri yerine düz bash sözdizimi kullanıyor ve görevler çalışırken size önemli ölçüde daha iyi bir terminal çıktısı sağlıyor.
Freek Van der Herten konu üzerinde blogunda şöyle yazmış: “Laravel Cloud gibi hizmetler, sunucuları asla düşünmemeyi mümkün kılarken, bazı projeler için kendi sunucularıma deploy yapmayı tercih ederim.” Scotty’nin hedef aldığı senaryo tam olarak bu. DigitalOcean, Hetzner gibi kendi yönettiğiniz bir sunucuda iseniz ve ya hala manuel olarak SSH ile giriş yapıyor ya da Envoy kullanıyorsanız, Scotty’yi denemeye değer.
Şimdi farklı ne yaptığına, anlamlı bir yükseltme olup olmadığına ve nasıl geçiş yapabileceğinize veya sıfırdan nasıl kurabileceğinize bakalım.
Laravel Envoy ile Problemler
Laravel Envoy ile Problemler
Envoy çalışıyor. Bunun bozuk olduğunu iddia etmeyeceğim. Ancak, her zaman kullandığınızda ortaya çıkan iki sürtüşme noktası var.
İlki, Blade dosya formatı. Deploy script’iniz bir Envoy.blade.php dosyasıdır ve içinde @task, @servers, @story direktifleri ve {{ $variable }} sözdizimi bulunur. Görünümü PHP’ye benziyor, ama tam olarak PHP değil. Editörünüz, Blade desteğinizin nasıl yapılandırıldığına bağlı olarak bunu farklı şekilde ele alıyor. Shell linting bunu kontrol etmiyor. Bash komutları için otomatik tamamlama Blade bloklarının içinde çalışmıyor. Bu, esasen bir shell scripting görevi için biraz tuhaf olan bir melez format.
İkincisi çıktı. Envoy çalışırken, komutları ardışık olarak düz bir akış içinde görüyorsunuz. Adım sayacı, her görev için geçen zaman yok, sonunda bir özet yok. 40 saniye süren bir işlem gözlerinizin önünde metinlerin kaybolmasına neden oluyor, bir şeylerin yanlış olup olmadığını umursayarak.
Scotty, her iki sorunu da doğrudan ele alıyor.
Scotty’nin Farklı Yaptığı Şeyler
Scotty’nin Farklı Yaptığı Şeyler
Düz bash ile not yorumları. Script’iniz bir Scotty.sh dosyasıdır ve #!/usr/bin/env scotty shebang ile başlar. Görevler, standart bash fonksiyonlarıdır. Sunucu hedefleri ve makrolar, not yorumlarıyla tanımlanır. Görünümü şöyle:
#!/usr/bin/env scotty
# @servers [email protected]
# @macro deploy pullCode runComposer runMigrations clearCaches restartWorkers
APP_DIR="/var/www/my-app"
BRANCH="${BRANCH:-main}"
# @task on:remote confirm="Deploy to production?"
pullCode() {
cd $APP_DIR
git pull origin $BRANCH
}
# @task on:remote
runComposer() {
cd $APP_DIR
composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev
}
# @task on:remote
runMigrations() {
cd $APP_DIR
php artisan migrate --force
}
# @task on:remote
clearCaches() {
cd $APP_DIR
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
}
# @task on:remote
restartWorkers() {
cd $APP_DIR
php artisan horizon:terminate
}
Bu, tam bir deploy script’idir. Unutmayın ki BRANCH="${BRANCH:-main}" tamamen bash komutudur. Varsayılan olarak main‘dir ve komut satırından bir geçersiz kılma alır. Blade interpolasyonu gerektirmez. Editörünüz bunu doğru bir şekilde vurgular. shellcheck ile lint edilebilir. Bash otomatik tamamlama, fonksiyonlar içinde çalışır.
Canlı çıktı ile özet tablo. Görevler çalışırken, Scotty her birinin adını, bir adım sayacını, geçen süreyi ve o anda çalışan komutu gösterir. Her şey bittiğinde, her adımın ne kadar sürdüğünü gösteren bir özet tablo alırsınız. Küçük bir şey ama bir deploy süresi iki dakika alıyorsa, üç saniyelik Composer yüklemesinin sorunlu olup olmadığını bilmek önemlidir.
Durma ve devam etme. Bir deploy’u yarıda kesmeniz gerektiğinde, p tuşuna basın ve Scotty mevcut görevin bitmesini bekler, ardından durur. Devam etmek için Enter tuşuna basmanız yeterli. Bu durum, bir sıcak düzeltmeyi gece yarısı yaparken bir şeylerin yanlış göründüğü anlarda daha önemlidir.
Scotty doktor komutu. İlk deploy’dan önce scotty doctor komutunu çalıştırın, böylece Scotty.sh dosyanızı doğrular, her sunucuya SSH bağlantısını test eder ve uzak makinede PHP, Composer ve Git’in kurulu olup olmadığını kontrol eder. Bu, deploy başlamadan çoğu kurulum sorununu tespit eden bir ön kontrol.
–pretend modu. Bir sunucuda ilk kez bir deploy çalıştırmadan önce --pretend bayrağını ekleyin:
scotty run deploy --pretend
Scotty, gerçekte bağlanmadan ne tür bir SSH komutu çalıştıracağını yazdırır. scotty doctor kurulumunuzu kontrol eder. --pretend script mantığınızı kontrol eder. Üretime dokunmadan önce her iki komutu da çalıştırın.
Scotty Kurulumu
Scotty Kurulumu
Onu global bir Composer paketi olarak kurun:
composer global require spatie/scotty
Composer’ın global bin dizininin $PATH içinde bulunduğundan emin olun. Nereye olduğunu bilmiyorsanız:
composer global config bin-dir --absolute
Yükledikten sonra çalıştığını doğrulayın:
scotty list
Projenizde yeni bir Scotty dosyası oluşturmak için şu komutu çalıştırın:
scotty init
Bu, sunucu SSH bağlantı dizesini ister ve başlangıç Scotty.sh dosyasını oluşturur. Ya da dosyayı manuel olarak da oluşturabilirsiniz. Formatı oldukça basit, bu nedenle bir jeneratöre gerçekten ihtiyacınız yok.
Envoy’dan Geçiş
Envoy’dan Geçiş
Bir Envoy.blade.php dosyanız varsa, hemen yeniden yazmanız gerekmez. Scotty, Envoy dosyalarını kutudan çıkar çıkmaz okur. Sadece scotty run deploy komutunu var olan Envoy dosyanıza karşı çalıştırın ve çalışır.
Geçiş etmeye hazır olduğunuzda yerleşik mantık açıktır:
| Envoy | Scotty.sh |
|---|---|
@servers(['web' => 'user@host']) | # @servers remote=user@host |
@story('deploy') ... @endstory | # @macro deploy task1 task2 |
@task('pullCode', ['on' => 'web']) | # @task on:remote ardından pullCode() { } |
{{ $branch }} | $BRANCH (düz bash değişkeni) |
@setup $branch="main"; @endsetup | BRANCH="${BRANCH:-main}" dosyanın üst tarafında |
Görevlerin içindeki gerçek shell komutları hiçbir değişiklik göstermez. Sadece sarmalayıcıları yeniden yazıyorsunuz.
Sıfır Kesinti ile Deploy
Sıfır Kesinti ile Deploy
Bu, Scotty’nin üretim uygulamaları için parladığı yer. Scotty belgeleri, tam bir sıfır kesinti ile deploy script’i içerir ve bu, Spatie’nin tüm kendi uygulamalarında kullandığı aynı yapıdır.
Fikir şu: dosyaları yerinde güncellemek yerine (bu, her zaman kodunuzun yarı güncellenmiş olduğu bir pencere vardır), her sürümü yeni bir zaman damgalı dizine kopyalayıp her şey hazır olduğunda bir symlink değiştirirsiniz. Sunucudaki dizin yapısı şöyle görünür:
/var/www/my-app/
├── current -> /var/www/my-app/releases/20260406-140000
├── persistent/
│ └── storage/
├── releases/
│ ├── 20260406-130000/
│ └── 20260406-140000/
└── .env
Nginx belge kökünüz /var/www/my-app/current/public dizinine işaret eder. current symlink’i, başarılı bir deploy’un sonunda atomik olarak güncellenir. Eğer Composer başarısız olursa ya da bir migration bozulursa, current hâlâ son çalışan sürüme işaret eder ve kullanıcılarınız yanlış bir şey görmez.
İşte tam sıfır kesinti script’i:
#!/usr/bin/env scotty
# @servers local=127.0.0.1 [email protected]
# @macro deploy startDeployment cloneRepository runComposer buildAssets updateSymlinks migrateDatabase blessNewRelease cleanOldReleases
BASE_DIR="/var/www/my-app"
RELEASES_DIR="$BASE_DIR/releases"
PERSISTENT_DIR="$BASE_DIR/persistent"
CURRENT_DIR="$BASE_DIR/current"
NEW_RELEASE_NAME=$(date +%Y%m%d-%H%M%S)
NEW_RELEASE_DIR="$RELEASES_DIR/$NEW_RELEASE_NAME"
REPOSITORY="your-org/your-repo"
BRANCH="${BRANCH:-main}"
# @task on:local
startDeployment() {
git checkout $BRANCH
git pull origin $BRANCH
}
# @task on:remote
cloneRepository() {
[ -d $RELEASES_DIR ] || mkdir -p $RELEASES_DIR
[ -d $PERSISTENT_DIR ] || mkdir -p $PERSISTENT_DIR
[ -d $PERSISTENT_DIR/storage ] || mkdir -p $PERSISTENT_DIR/storage
cd $RELEASES_DIR
git clone --depth 1 --branch $BRANCH [email protected]:$REPOSITORY $NEW_RELEASE_NAME
}
# @task on:remote
runComposer() {
cd $NEW_RELEASE_DIR
ln -nfs $BASE_DIR/.env .env
composer install --prefer-dist --no-dev -o
}
# @task on:remote
buildAssets() {
cd $NEW_RELEASE_DIR
npm ci
npm run build
rm -rf node_modules
}
# @task on:remote
updateSymlinks() {
rm -rf $NEW_RELEASE_DIR/storage
cd $NEW_RELEASE_DIR
ln -nfs $PERSISTENT_DIR/storage storage
}
# @task on:remote
migrateDatabase() {
cd $NEW_RELEASE_DIR
php artisan migrate --force
}
# @task on:remote
blessNewRelease() {
ln -nfs $NEW_RELEASE_DIR $CURRENT_DIR
cd $NEW_RELEASE_DIR
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
php artisan cache:clear
php artisan horizon:terminate
sudo service php8.4-fpm restart
}
# @task on:remote
cleanOldReleases() {
cd $RELEASES_DIR
ls -dt $RELEASES_DIR/* | tail -n +4 | xargs rm -rf
}
Şu komutla çalıştırın:
scotty run deploy
Veya belirli bir dalı deploy etmek için:
scotty run deploy --branch=develop
Bu script ile ilgili birkaç nokta dikkat çekicidir. startDeployment görevi yerel olarak çalışır: sunucuda bir şeylerle oynamadan önce dalı makinenizde kontrol eder ve çeker, böylece herhangi bir git çakışmasını yakalamış olursunuz. blessNewRelease görevi, symlink’in gerçekten değiştiği yerdir, bu nedenle bu adımdan önce her şey başarısızlığa uğrayabilir. cleanOldReleases, diskte en son üç güncel sürümü tutar, böylece birini inceleme ihtiyacınız olursa bulabilirsiniz.
Eğer Horizon ile kuyruk işçileri çalıştırıyorsanız, php artisan horizon:terminate mevcut görevler bitince yeni kod ile Supervisor’ı yeniden başlatması için talimat verir. Eğer bir Laravel queue kurulumunuz varsa, bu adım en son iş tanımlarınızı alır.
Peki Geçiş Yapmaya Değer Mi?
Peki Geçiş Yapmaya Değer Mi?
Yeni bir projeye başlıyorsanız: evet, baştan itibaren Scotty kullanın. Bash formatı, shell scripting için Blade’den kesinlikle daha iyidir ve geçiş maliyeti yoktur.
Eğer Envoy’daysanız ve çalışıyorsa: geçiş düşük çabalar gerektiriyor çünkü Scotty mevcut dosyalarını olduğu gibi okur. Soru, çıktı iyileştirmeleri ve scotty doctor‘nın zamanınızın 20 dakikasına değip değmeyeceğidir. Çoğu proje için değiyor.
Eğer Laravel Forge’un yerleşik deploy’unda iseniz: Scotty sizin için değil. Forge bunu iyi bir şekilde yönetir ve size bir arayüz sunar. Scotty, terminal tabanlı kontrol ve repo içinde yaşayan sürüm kontrollü deploy script’lerine ihtiyacı olan geliştiriciler içindir.
Eğer Laravel Cloud’daysanız: yine sizin için değil. Cloud’un tüm amacı, sunucuları yönetmemenizdir. Scotty spesifik olarak, bir plain VPS ili Dockerize edilmiş Laravel kurulumu gibi kendi barındırdığınız uygulamalar içindir.
Samimi bir değerlendirme: Scotty, temiz ve iyi düşünülmüş bir araçtır. Deployment’ı yeniden icat etmez, sadece script formatını mantıklı hale getirir ve çıktıyı okunabilir kılar. Kendi başına barındırdığınız Laravel uygulamalarını kullanan herkes için, Envoy’dan geçiş yapmak için belli başlı araçtır. Otomasyona dair bir kurulum yapmadıysanız, belgeler güvenilir bir üretim hazır scripti ile başlamanızı sağlar.
Sıkça Sorulan Sorular
Sıkça Sorulan Sorular
Scotty birden fazla sunucu ile çalışır mı?
Evet. # @servers satırında birden fazla sunucu tanımlayabilir ve bireysel görevlerde on:web, on:workers gibi belirtebilirsiniz. Ayrıca parallel seçeneğini ekleyerek görevleri birden fazla sunucuda paralel olarak çalıştırabilirsiniz.
Bir görev ve bir makro arasındaki fark nedir?
Bir görev, bir hedef üzerinde çalışan bir shell komutları işlevselliğidir, yerel ya da uzaktan. Bir makro ise görevlerin adlandırılmış bir dizisidir. Gerçekten scotty run deploy ile çalıştırdığınız şeydir. Makroları deploy pipeline tanımınız olarak düşünün.
Scotty’i CI/CD’de çalıştırabilir miyim?
Evet. Global bir Composer paketi olduğu için, lokalde yaptığınız gibi CI ortamınızda da kurabilirsiniz. SSH erişiminiz olan her yerde çalışır.
Bir görev deploy esnasında başarısız olursa ne olur?
Scotty, hemen başarısız olan görevde durur ve hata çıktısını gösterir. Eğer sıfır kesinti script’ini kullanıyorsanız, current symlink henüz güncellenmemiştir, bu nedenle canlı uygulamanız etkilenmez.
Scotty.sh dosyasını repo’ya eklemem gerekli mi?
Evet, bu önerilen yaklaşımdır. Script, kodunuzla birlikte versiyon kontrolünde yer alır, bu nedenle tüm ekibiniz aynı deploy sürecine erişebilir ve üzerinde yapılacak değişiklikler normal kod incelemesi yoluyla gitmelidir.
Scotty’nin belgeleri spatie.be/docs/scotty‘da bulunabilir ve kaynak kodu GitHub‘da mevcuttur. Sunucu kurulumunuzu oluşturuyorsanız ve deploy otomasyon eklemeden önce güçlendirmek istiyorsanız, VPS güvenlik kılavuzum yeni bir DigitalOcean droplet üzerinde SSH anahtarları, Cloudflare ve Tailscale hakkında kapsamlı bilgiler sunar.
Eğer otomatik deploy’lar ilk aşama aşamasındaysanız ve bunun farkında değilseniz, bize ulaşın. Deploy pipeline’ını doğru bir şekilde oluşturmak, ilerleyen dönemlerde çok acıdan tasarruf etmenizi sağlar.
Kaynak: Orijinal Makale


