Laravel Envoy Cara Deploy Laravel Otomatis dengan Git Repositories

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.

Sumber : github.com/papertank/envoy-deploy