ZERO downtime Laravel deployment with Laravel Deployer

Hi Folks! Today we are going to look at a neat trick I've been using in the past to deploy laravel applications without having to worry about breaking the production site. I am serious here, no downtime and we have an added bonus of rollbacks if we deploy a wrong release. Sounds fun? Let's get started. :) 

Summary

  1. Prepping the server
  2. Prepping your VCS account
  3. Installing lorisleiva/laravel-deployer
  4. Configuring the deploy script 
  5. Conclusion

Step 1. Prepping the server

In this article, I am going to assume that you are using a Linux server if you are using anything other that then you should leave now. Lol, I am kidding... Seriously, you should leave right away. 

I am going to also assume that you have a server with LEMP/LAMP stack running. If not please follow this article to see how you can set up a Linux server for your laravel app. 

To follow this tutorial you only need the following from your server. 

  1. SSH access credentials to your server 
  2. Path to your webroot

Step 2. Prepping your VCS (Github/Bitbucket/Gitlab) account

Laravel deployer doesn't deploy the code in your local machine, in fact, it connects to your vcs account to pull the latest code and deploy it in the server. 

I prefer having multiple branched in my repository. I usually have the following branches 

  1. live
  2. staging
  3. uat

I deploy live branch to production, uat for user acceptance testing and staging for development testing.

Since our project repos are usually private, we need to give access to our repo from our server. To do that we need to add our servers public key to our vcs account. If you are using github then you can go to https://github.com/settings/keys and add your servers public key there.

Your servers public key is available at ~/.ssh/id_rsa 

Step 3. Installing lorisleiva/laravel-deployer

Make sure to check the documentation of laravel deployer here

composer require lorisleiva/laravel-deployer

once the package is installed, run php artisan deploy:init command to generate you deployment config file. It will ask a series of question about your project. It's pretty straigh forward, you can answer the or skip and later change the values on config/deploy.php

php artisan deploy:init

Step 4. Configuring the deploy script

Let's try to break the some of the important parts of the deploy.php file. 

    'hooks' => [
...
        'ready' => [
            'artisan:storage:link',
            'artisan:view:clear',
            'artisan:cache:clear',
            'artisan:config:cache',
            'artisan:migrate',
        ],
        'done' => [
            'fpm:reload',
        ],
...
    ],
...
'options' => [
    'application' => env('APP_NAME', 'Laravel'),
    'repository' => 'git@github.com:fawzanm/example.git',
    'php_fpm_service' => 'php7.3-fpm',
],
...
'hosts' => [
    'example.com' => [
        'deploy_path' => '/var/www/example.com/current',
        'user' => 'john',
        'branch' => 'live',
        'stage' => 'live',

    ],
],
...


Above I have picked some of the important parts of the deploy.php file. You need to configure this properly with your project-specific 

One very important thing to notice is deploy_path because we are using ZERO downtime deployment, we will have three folders in /var/www/example.com 

Make sure to point the current folder as your deployment path. 

Once this is done, You can run the command php artisan deploy live to deploy your project.

If you want to rollback to the previous release, you can do that with php artisan deploy:rollback live

5. Conclusion

Once again, Don't stop here. Do read the documentation for more options, You can have more than one hosts setup in the hosts array to set up your staging and uat environments.

Feel free to comment here if you have any questions or suggestions. If you get any issues don't break your head. I can help you debug your code. Feel free to request a session from me on codementor

I'll see you in another post. Have a nice day :) 


Related articles

Signature Pad with Alpine.js

The post describes the implementation of signature pads with Alpine.js. It also discusses how to integrate it with laravel livewire.