Zero Downtime Laravel Forge Deploys

So you’re a Laravel developer and of course you are using Forge to manage your servers. You enjoy how simple Forge makes it to deploy your applications but you may notice a few seconds of downtime when your app is updating packages etc. To solve this you could use Envoyer, from Taylor Otwell or hack together you own solution.

After some searching I came across a gist from rap2hpoutre. It works by making a copy of your existing application and updating the copy of your app(git, composer, migrations, etc). Then it moves your current application to a new backup folder and replaces your live site with the newly updated files. This enables you to revert back if something goes wrong. Make sure you rename the folders so they are unique per project if you are hosting multiple apps on the same server.

# stop script on error signal
set -e

# remove old deployment folders
if [ -d "/home/forge/weather-deploy" ]; then
 rm -R /home/forge/weather-deploy
fi
if [ -d "/home/forge/weather-backup" ]; then
 rm -R /home/forge/weather-backup
fi

cp -R /home/forge/weather.timleland.com /home/forge/weather-deploy

# Update
cd /home/forge/weather-deploy
git pull origin master
composer dump-autoload
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
php artisan cache:clear
php artisan route:cache
php artisan view:clear 
php artisan migrate --force

# Switch (downtime for microseconds)
mv /home/forge/weather.timleland.com /home/forge/weather-backup
mv /home/forge/weather-deploy /home/forge/weather.timleland.com

After updating the script for my projects and saving it as my deploy script on Forge, I was able to deploy my Weather app with virtually zero downtime. Its great to know I can deploy at anytime without upsetting users.

Let me know your thoughts and how this could be improved in the comments below.


Thanks for reading. Make sure you follow me on Twitter to stay up to date on the progress of my side projects T.LYWeather Extension, and Link Shortener Extension. If you are interested in the tech I use daily, check out my uses page.  

7 thoughts to “Zero Downtime Laravel Forge Deploys”

  1. I would add “–no-dev” to the composer install line so that dev-only packages aren’t installed. “php artisan opcache:clear” isn’t available by default, it’s part of the “laravel-opcache-clear” package, which probably isn’t used much any more. I would also consider adding “php artisan config:cache” (as long as you aren’t using env() except in your config files).

  2. I use config cache, so it needs to be at the end, as the opcache too. Below my deploy strategy:

    “`
    export DOMAIN=api.ckp.io
    export FOLDER_DOM=/home/forge/$DOMAIN
    export FOLDER_DEP=/home/forge/deploy-$DOMAIN
    export FOLDER_BKP=/home/forge/backup-$DOMAIN

    # stop script on error signal
    set -e

    # remove old deployment folders
    rm -rf “$FOLDER_BKP” “$FOLDER_DEP”

    cp -R $FOLDER_DOM $FOLDER_DEP

    # Update
    cd $FOLDER_DEP
    git pull origin master
    composer install –no-dev –no-interaction –prefer-dist –optimize-autoloader

    php artisan migrate –force
    php artisan route:cache # never use clousures in routes, use controller methods
    php artisan view:clear
    php artisan view:cache

    # Switch (downtime for microseconds)
    mv $FOLDER_DOM $FOLDER_BKP
    mv $FOLDER_DEP $FOLDER_DOM

    cd $FOLDER_DOM

    php artisan config:cache # never use env() outside of config files
    echo “” | sudo -S service php7.2-fpm reload
    “`

Leave a Reply

Your email address will not be published. Required fields are marked *