Beberapa hari yang lalu saya mencoba menggunakan Laravel Deployer untuk mendeploy Laravel saya di Versi 9. namun beberapa kali ada masalah ketika saya mencoba untuk mendeploy dengan package Deployer Package. Saat ini saya mengubah strategi untuk Mendeploy Laravel App saya menggunakan Package First Parti dari Laravel yang dinamakan Laravel Envoy dan teman-teman bisa melihat dokumentasinya disana.
Namun beberapa hal yang tidak bisa ditemukan di Laravel Envoy
ini tidak bisa sama dengan Deployer
. Untuk lebih jelasnya silahkan bandingkan sendiri ya. Nah sekarang yang akan saya bahas menggunakan Envoy Laravel. Mari Kita Setup :
Buatlah file Envoy.blade.php
di root
project kita :
dan untuk setup kita buat seperti ini :
@setup require __DIR__.'/vendor/autoload.php'; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); try { $dotenv->load(); $dotenv->required(['DEPLOY_SERVER', 'DEPLOY_REPOSITORY', 'DEPLOY_PATH'])->notEmpty(); } catch ( Exception $e ) { echo $e->getMessage(); exit; } $server = $_ENV['DEPLOY_SERVER'] ?? null; $repo = $_ENV['DEPLOY_REPOSITORY'] ?? null; $path = $_ENV['DEPLOY_PATH'] ?? null; $slack = $_ENV['DEPLOY_SLACK_WEBHOOK'] ?? null; $healthUrl = $_ENV['DEPLOY_HEALTH_CHECK'] ?? null; if ( substr($path, 0, 1) !== '/' ) throw new Exception('Careful - your deployment path does not begin with /'); $date = ( new DateTime )->format('YmdHis'); $env = isset($env) ? $env : "production"; $branch = isset($branch) ? $branch : "master"; $path = rtrim($path, '/'); $release = $path.'/releases/'.$date; @endsetup
Mari saya jelaskan sedikit tentang kode diatas :
require __DIR__.'/vendor/autoload.php';
ini nanti dibutuhkan untuk loader dari composer
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
Baris kode diatas untuk menarik data yang kita buat dari .env
file kita.
try { $dotenv->load(); $dotenv->required(['DEPLOY_SERVER', 'DEPLOY_REPOSITORY', 'DEPLOY_PATH'])->notEmpty(); } catch ( Exception $e ) { echo $e->getMessage(); exit; }
Jika ada file .env
maka akan kita gunakan, namun jika tidak ada maka akan exit
$server = $_ENV['DEPLOY_SERVER'] ?? null; $repo = $_ENV['DEPLOY_REPOSITORY'] ?? null; $path = $_ENV['DEPLOY_PATH'] ?? null; $slack = $_ENV['DEPLOY_SLACK_WEBHOOK'] ?? null; $healthUrl = $_ENV['DEPLOY_HEALTH_CHECK'] ?? null;
Bagian ini akan kita ambil dari .env yang sudah kita buat samplenya :
--- DEPLOY_SERVER=serverkamu.com DEPLOY_REPOSITORY=git@github.com:githubkamu/repokamu. DEPLOY_PATH=/var/www/html DEPLOY_HEALTH_CHECK=serverkamu.com --- ## Env Lainnya
Setup Servernya seperti ini :
@servers(['web' => $server])
setelah setup sudah semua sekarang kita buat lanjutannya, kita buat initial setup seperti ini :
@task('init') if [ ! -d {{ $path }}/storage ]; then cd {{ $path }} git clone {{ $repo }} --branch={{ $branch }} --depth=1 -q {{ $release }} echo "Repository cloned" mv {{ $release }}/storage {{ $path }}/storage ln -s {{ $path }}/storage {{ $release }}/storage echo "Storage directory set up" cp {{ $release }}/.env.example {{ $path }}/.env ln -s {{ $path }}/.env {{ $release }}/.env echo "Environment file set up" rm -rf {{ $release }} echo "Deployment path initialised. Edit {{ $path }}/.env then run 'envoy run deploy'." else echo "Deployment path already initialised (storage directory exists)!" fi @endtask
Penjelasan kode diatas adalah :
if [ ! -d {{ $path }}/storage ]; then // Jika di folder DEPLOY_PATH tidak ada folder storage else echo "Deployment path already initialised (storage directory exists)!" // Jika di folder DEPLOY_PATH sudah ada folder storage maka return nya echo fi
di function else
disini menentukan jika sudah melakukan initial atau sudah ada folder storage di folder DEPLOY_PATH
env yang tadi kita buat maka tidak akan dibuat lagi.
cd {{ $path }} git clone {{ $repo }} --branch={{ $branch }} --depth=1 -q {{ $release }} echo "Repository cloned"
Jika tidak ada maka Envoy akan clone dari repo dan branch yang kita tentukan nanti perintahnya.
mv {{ $release }}/storage {{ $path }}/storage ln -s {{ $path }}/storage {{ $release }}/storage echo "Storage directory set up"
Nah sekarang jika belum ada storage folder maka dibuatlah storage folder lalu di link ke release folder nantinya.
cp {{ $release }}/.env.example {{ $path }}/.env ln -s {{ $path }}/.env {{ $release }}/.env echo "Environment file set up"
Lalu proses diatas akan mengcopy file .env
jika belum ada maka akan di copy dari .env.example
menjadi .env
rm -rf {{ $release }} echo "Deployment path initialised. Edit {{ $path }}/.env then run 'envoy run deploy'."
Menghapus folder release jika memang sudah ada.
Setelah Setup kita beres seperti diatas maka kita sekarang akan membuat urutan task untuk mendeploy file-file laravel kita.
@story('deploy') deployment_start deployment_links deployment_composer deployment_migrate deployment_cache deployment_finish health_check deployment_option_cleanup @endstory
Diatas adalah urutan tasknya dan kita sekarang akan membuat tasknya.
Task No 1 : Clone Repositories
@task('deployment_start') cd {{ $path }} echo "Deployment ({{ $date }}) started" git clone {{ $repo }} --branch={{ $branch }} --depth=1 -q {{ $release }} echo "Repository cloned" @endtask
Penjelasan Task diatas Kita akan login ke server dan ke direktori DEPLOY_PATH
yang kita buat. lalu Proses dimulai, dan mengeluarkan echo
Deployment started, lalu akan di clone repo kita ke server dengan branch dari perintah kita.
Task No 2 : Remove Release Old
@task('deployment_links') cd {{ $path }} rm -rf {{ $release }}/storage ln -s {{ $path }}/storage {{ $release }}/storage echo "Storage directories set up" ln -s {{ $path }}/.env {{ $release }}/.env echo "Environment file set up" @endtask
Ditahap dua ini kita ke path direktori yang sudah kita targetkan di .env
dengan nama DEPLOY_PATH
dan menghapus storage dari release (sebelumnya). lalu akan kita link storagenya ke storage release terbaru kita begitu juga dengan .env
targetnya.
Task No 3 : Install Composer Package
@task('deployment_composer') echo "Installing composer dependencies..." cd {{ $release }} composer install --no-interaction --quiet --no-dev --prefer-dist --optimize-autoloader @endtask
Menginstall package-package dengan composer siapa tau ada package baru yang belum di install.
Task No 4 : Migrate Database
@task('deployment_migrate') php {{ $release }}/artisan migrate --env={{ $env }} --force --no-interaction @endtask
Melakukan migrasi dari schema database yang kita buat, dan belum ada di database server. namun jika sudah ada ini akan otomatis tidak termigrasi.
Task No 5 : Npm Package install & Run Production
@task('deployment_npm') echo "Installing npm dependencies..." cd {{ $release }} npm install --no-audit --no-fund --no-optional echo "Running npm..." npm run {{ $env }} --silent @endtask
Jika laravel teman-teman mempunya package-package npm maka bisa sekaligus menggunakan ini. seperti install bootstrap, inertia, livewire, tailwindcss dan lainnya. jadi ketika teman-teman ingin langsung proses npm production bisa juga memanfaatkan ini.
Task No 6 : Clear Cache and Config
@task('deployment_cache') php {{ $release }}/artisan view:clear --quiet php {{ $release }}/artisan cache:clear --quiet php {{ $release }}/artisan config:cache --quiet echo "Cache cleared" @endtask
Menghapus Cache dari semua yang dibuat dari sebelumnya dan membuat cache baru jika ada. Jadi nanti tidak perlu lagi memasukan perintah diatas.
Task No 7 : Restart Queue & Symbolic Links
@task('deployment_finish') php {{ $release }}/artisan storage:link echo "Storage symbolic links created" php {{ $release }}/artisan queue:restart --quiet echo "Queue restarted" ln -nfs {{ $release }} {{ $path }}/current echo "Deployment ({{ $date }}) finished" @endtask
Membuat symbolic links lagi untuk release terbaru hasil dari clone, dan merestart queue
jika teman-teman mengaktifkannya / mempunyai queue di aplikasinya. Lalu membuat symbolic links lagi ke current
app yang kita deploy.
Task No 8 : Cleanup Old Release
@task('deployment_option_cleanup') cd {{ $path }}/releases @if ( isset($cleanup) && $cleanup ) find . -maxdepth 1 -name "20*" | sort | head -n -4 | xargs rm -Rf echo "Cleaned up old deployments" @endif @endtask
Clean up untuk menghapus release sebelumnya.
Task No 9 : Health Check
@task('health_check') @if ( ! empty($healthUrl) ) if [ "$(curl --write-out "%{http_code}\n" --silent --output /dev/null {{ $healthUrl }})" == "200" ]; then printf "\033[0;32mHealth check to {{ $healthUrl }} OK\033[0m\n" else printf "\033[1;31mHealth check to {{ $healthUrl }} FAILED\033[0m\n" fi @else echo "No health check set" @endif @endtask
Pengecekan apakah ada response dari web app yang kita deploy apa tidak nya.
Demikian artikel Laravel Envoy Cara Deploy Laravel Otomatis dengan Git Repositories saya buat agar bisa sharing pengalaman saya ke teman-teman.
Semoga bermanfaat.