Iman Sugirman

Laravel Envoy Cara Deploy Laravel Otomatis dengan Git Repositories

16 April 2022

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 :

Buat File Envoy.blade.php

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.

Memulai Membuat Urutan Envoy Laravel

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.