Deployment Automation with Laravel Envoy 🚀

author

José Rafael Gutierrez

2 months ago

Introduction

Laravel Envoy is a simple yet powerful tool that allows you to automate deployment and server management tasks in development and production environments. With a clean syntax similar to Blade, Envoy makes it easy to execute remote tasks on one or multiple servers without hassle. In this article, we’ll go through the installation, configuration, and execution of commands with Laravel Envoy, along with some practical examples to automate application deployment.

Prerequisites

Before starting, make sure you have:

  1. SSH access configured on your servers for each environment (~/.ssh/id_rsa).
  2. A Laravel project already deployed in each environment.
  3. Branches configured for each environment; in our example, we'll use three:
    • dev for development.
    • qa for QA.
    • master for production.

Step 1: Install Envoy in the Project

To install Envoy only in the project, add the development dependency by running the following command:

composer require laravel/envoy --dev

This will add Envoy to your project, allowing you to run it only within the context of this project and ensuring that each environment or developer has the same version.

Step 2: Create the Envoy.blade.php File

In the root directory of your project, create a file called Envoy.blade.php. This file will be the core of the deployment configurations for the dev, QA, and prod environments.

touch Envoy.blade.php

Step 3: Configure the Environments

Define the environments in the Envoy.blade.php file using the @servers directive to specify the IP addresses of each server and the SSH user to connect. In this example, we’ll use user@your-server-ip and the SSH key at ~/.ssh/id_rsa.

Configuration Example

@servers([
    'dev' => 'user@dev-your-server-ip',
    'qa' => 'user@qa-your-server-ip',
    'prod' => 'user@prod-your-server-ip',
])

@setup
    // Directory where the project is hosted on each server
    $appDir = '/var/www/laravel-project';
    
    // Git branches corresponding to each environment
    $branches = [
        'dev' => 'dev',
        'qa' => 'qa',
        'prod' => 'master',
    ];

    // Check if the deployment environment is defined
    if (!isset($server)) {
        throw new Exception("Environment not defined. Use --server=dev|qa|prod");
    }
@endsetup

With this setup, @servers defines the SSH access for each environment, and @setup establishes the base project directory and the corresponding branches.

Step 4: Create the Deployment Tasks

Configure the deployment tasks for each environment. These tasks will perform the following actions:

  1. Navigate to the project directory on the server.
  2. Update the code from the corresponding branch using git pull.
  3. Run migrations (optional).
  4. Clear the application cache to ensure changes are applied correctly.

Deployment Task

@task('deploy', ['on' => $server])
    echo "Starting deployment in environment: {{ $server }}...";
    
    cd {{ $appDir }};
    git pull origin {{ $branches[$server] }};
    
    echo "Running migrations...";
    php artisan migrate --force;
    
    echo "Clearing cache...";
    php artisan optimize:clear;
    
    echo "Deployment completed for environment {{ $server }}.";
@endtask

In this task:

  • git pull origin {{ $branches[$server] }} updates the code based on the specified branch for the environment (dev, qa, or master).
  • php artisan migrate --force runs necessary migrations in the environment.
  • php artisan optimize:clear clears the cache to apply any configuration or code changes.

Step 5: Additional Common Tasks

In addition to the deployment task, you can set up other tasks to handle specific aspects of your application, such as clearing the cache or generating a sitemap. These additional tasks facilitate the administration and maintenance of the application.

Clear Cache

@task('cache:clear', ['on' => $server])
    echo "Clearing cache in environment {{ $server }}...";
    cd {{ $appDir }};
    php artisan optimize:clear;
    echo "Cache cleared in {{ $server }}.";
@endtask

Generate Sitemap

@task('sitemap:generate', ['on' => $server])
    echo "Generating sitemap in environment {{ $server }}...";
    cd {{ $appDir }};
    php artisan sitemap:generate;
    echo "Sitemap generated in {{ $server }}.";
@endtask

Step 6: Running the Tasks

To execute the deployment tasks, use the envoy run command followed by the task you want to run and the environment (--server=dev, --server=qa, or --server=prod).

Example Execution

  1. Deployment in Development (dev):
envoy run deploy --server=dev
  1. Deployment in QA:
envoy run deploy --server=qa
  1. Deployment in Production (prod):
envoy run deploy --server=prod

Similarly, you can execute the cache-clearing or sitemap-generation tasks in any environment:

envoy run cache:clear --server=qa
envoy run sitemap:generate --server=prod

Security Tips

  1. SSH Permissions: Ensure that only authorized users have access to the SSH keys in ~/.ssh/id_rsa.
  2. Backups and QA Testing: Always conduct tests in the QA environment before deploying changes to production.
  3. Isolated Environments: Each environment should have its own database and configurations to avoid data overwrite issues or conflicts.

Conclusion

With Laravel Envoy, you can simplify and automate the deployment of your applications across multiple environments. This example shows how to configure an efficient and secure deployment setup on dev, QA, and production servers, managing the corresponding branches and using custom commands to maintain the application.

For larger projects, Envoy is a tool that helps save time and minimize errors, providing an organized and repeatable deployment flow across multiple environments. Try Envoy on your project, and see the benefits of automation in action!

José Rafael Gutierrez

Soy un desarrollador web con más de 14 años de experiencia, especializado en la creación de sistemas a medida. Apasionado por la tecnología, la ciencia, y la lectura, disfruto resolviendo problemas de...

Subscribe for Updates

Provide your email to get email notifications about new posts or updates.