At Purpose Built, we use Laravel Forge to manage our servers and auto-deploy code to projects. Forge is great, and really simplifies these things.
Forge provides a basic deploy script to do all the things that need to happen to deploy the application, things like:
- Pull the most recent code
- Update composer libraries
- Update JS libraries
- Compile JS code
- Run database migrations
- Restart PHP-FPM
This process usually takes about a minute to run. While this deploy script us running, a user might happen to interact with the application, and it’s hard to say what they are going to see.
So to improve this, we added a little enhancement:
- php artisan down
- all the good stuff from before
- php artisan up
Now, once the deploy script starts, the application shows an Under Maintenance page, with some helpful text like “Please excuse us while we are updating our bits”.
This is way better than the first script because we know what users might be seeing, and should cause less confusion, and most importantly, cause less distrust in the platform.
Still… there’s a better way… Zero Downtime deploy.
Why is it better? Because Zero (almost) Downtime is better than a minute of user disruption, for the same reason as Six Minute Abs are better than Seven Minute Abs.
For Zero Downtime, we updated the deploy script to do all the same things as the first script, but not in the live application directory.
- We copy the latest live directory over to a new deploy directory. This brings all the things like log files and other stuff in the public and storage directories of the Laravel framework.
- Do all the stuff from the first script up to running the DB migrations
- Here’s the fun part, we run two very fast sequential commands
- Move the directory of the live application to a backup directory
- Move the directory of the new code to the live application directory
- Run database migrations
- Restart PHP-FPM
The directory switch is the key. Because of how the UNIX / LINUX filesystem works, it is super fast to move a directory… it doesn’t actually move the bits, it just updates the pointer of where on disk the directory points to, if that makes sense. Unlike copying that can take a long time, moving the directory usually takes micro seconds.
Here’s a generic version of our Zero Downtime Laravel Forge deploy script: