Laravel Envoy Deployment Configuration

February 16, 2024

Server Configuration

@setup
$__container->servers([
    'staging' => 'user@ip_address',
    'production' => ['user@ip_address -p 8288'],
]);
@endsetup

Environment Setup

@setup
$repository = '[email protected]:username/awesome_project_ever.git';
$releases_dir = '/var/www/html/app/awesome_project_ever/releases';
$app_dir = '/var/www/html/app/awesome_project_ever';
$release = date('YmdHis');
$new_release_dir = $releases_dir .'/'. $release;
$branch = isset($branch) ? $branch : "master";
if($server == "staging"){
    $branch = "staging";
}
@endsetup

Deployment Story

@story('deploy',['on' => $server,'parallel' => true])
clone_repository
run_composer
update_symlinks
deployment_migrate
deployment_cache
clean_old_releases
set_permission_folder
say_finished
@endstory

Task Definitions

Clone Repository

@task('clone_repository')
echo 'Cloning repository'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
git clone --depth 1 {{ $repository }} --branch={{ $branch }} {{ $new_release_dir }}
@endtask

Run Composer

@task('run_composer')
echo "Starting deployment ({{ $release }})"
cd {{ $new_release_dir }}
composer install --prefer-dist --no-scripts -q -o
@endtask

Update Symlinks

@task('update_symlinks')
echo "Linking storage directory"
cp -R {{ $new_release_dir }}/storage {{ $app_dir }}
rm -rf {{ $new_release_dir }}/storage
ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage

cp -R {{ $new_release_dir }}/public {{ $app_dir }}
rm -rf {{ $new_release_dir }}/public/images
ln -nfs {{ $app_dir }}/public/images {{ $new_release_dir }}/public/images

echo 'Linking .env file'
ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env

echo 'Linking current release'
ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask

Database Migration

@task('deployment_migrate')
echo "Migrating..."
php {{ $new_release_dir }}/artisan migrate --force --no-interaction
@endtask

Cache Management

@task('deployment_cache')
echo "clearing cache..."
php {{ $new_release_dir }}/artisan cache:clear --quiet
php {{ $new_release_dir }}/artisan config:clear
echo "Cache cleared"
@endtask

Cleanup Old Releases

@task('clean_old_releases')
echo "Cleaning old releases ..."
rm -rf `ls -dt {{ $app_dir }}/releases/* | tail -n +4`
@endtask

Set Permissions

@task('set_permission_folder')
echo "Set permission folder"
cd {{ $app_dir }}
sudo chgrp -R www-data storage public
sudo chmod -R ug+rwx storage public

cd {{ $app_dir }}/current
sudo chgrp -R www-data bootstrap/cache
sudo chmod -R ug+rwx bootstrap/cache
@endtask

Slack Notification

@finished
@slack('https://hooks.slack.com/services/(Kode)', '#gitlab-activities', "Deployed {$server}")
@endfinished

Prerequisites

  • Create .env file
  • Create folder storage
  • Create folder public/images

Usage

For staging deployment:

envoy run deploy --server=staging

For production deployment:

envoy run deploy --server=production

Full Code



            @setup
$__container->servers([
    'staging' => 'user@ip_address',
    'production' => ['user@ip_address -p 8288'],
]);
@endsetup

@setup
    $repository = '[email protected]:username/awesome_project_ever.git';
    $releases_dir = '/var/www/html/app/awesome_project_ever/releases';
    $app_dir = '/var/www/html/app/awesome_project_ever';
    $release = date('YmdHis');
    $new_release_dir = $releases_dir .'/'. $release;
    $branch = isset($branch) ? $branch : "master";
    if($server == "staging"){
        $branch = "staging";
    }
@endsetup

@story('deploy',['on' => $server,'parallel' => true])
    clone_repository
    run_composer
    update_symlinks
    deployment_migrate
    deployment_cache
    clean_old_releases
    set_permission_folder
    say_finished
@endstory

@task('clone_repository')
    echo 'Cloning repository'
    [ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
    git clone --depth 1 {{ $repository }} --branch={{ $branch }} {{ $new_release_dir }}
@endtask

@task('run_composer')
    echo "Starting deployment ({{ $release }})"
    cd {{ $new_release_dir }}
    composer install --prefer-dist --no-scripts -q -o
@endtask

@task('update_symlinks')
    echo "Linking storage directory"
    cp -R {{ $new_release_dir }}/storage {{ $app_dir }}
    rm -rf {{ $new_release_dir }}/storage
    ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage

    cp -R {{ $new_release_dir }}/public {{ $app_dir }}
    rm -rf {{ $new_release_dir }}/public/images
    ln -nfs {{ $app_dir }}/public/images {{ $new_release_dir }}/public/images

    echo 'Linking .env file'
    ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env

    echo 'Linking current release'
    ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask

@task('deployment_migrate')
    echo "Migrating..."
    php {{ $new_release_dir }}/artisan migrate --force --no-interaction
@endtask

@task('deployment_cache')
    echo "clearing cache..."
    php {{ $new_release_dir }}/artisan cache:clear --quiet
    php {{ $new_release_dir }}/artisan config:clear
    echo "Cache cleared"
@endtask

@task('clean_old_releases')
  echo "Cleaning old releases ..."
  rm -rf `ls -dt {{ $app_dir }}/releases/* | tail -n +4`
@endtask

@task('set_permission_folder')
    echo "Set permission folder"
    cd {{ $app_dir }}
    sudo chgrp -R www-data storage public
    sudo chmod -R ug+rwx storage public

    cd {{ $app_dir }}/current
    sudo chgrp -R www-data bootstrap/cache
    sudo chmod -R ug+rwx bootstrap/cache
@endtask


@finished
    @slack('https://hooks.slack.com/services/(Kode)', '#gitlab-activities', "Deployed {$server}")
@endfinished

@task('say_finished')
    echo "Finished..."
@endtask



{{--

create .env
create folder storage
create folder public/images

How to run : 
if staging
envoy run deploy --server=staging

if production
envoy run deploy --server=production

--}}
        
#Laravel #Envoy #Deployment #DevOps #Automation