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.LY, Weather Extension, and Link Shortener Extension. If you are interested in the tech I use daily, check out my uses page.
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).
Thanks David those are all good points. I’ll update the post
Envoyer is my go to choice for zero downtime deployment. I often use CW+Envoyer combo when deploying php apps (https://www.cloudways.com/blog/php-laravel-envoyer-deployment/ ). It makes the entire process of setting up a server and app much easier and quicker.
Great article!
Thanks!
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
“`
Thanks for sharing!