Laravel Envoyer is a great tool that reduces the pain from automating the deployments of your projects. According their marketing page they offer "Zero Downtime PHP Deployment".
Similar to the open source Deployer, Envoyer is stores new builds inside new and separate release folders.
After running all the commands needed for creating the new build (like composer install, artisan migrate etc), the new build is ready to release. Envoyer then creates a symlink linking the nginx public root to the new release directory.
In this sense, it's a zero downtime deployment because the creation of a symlink is almost instant. However there is a catch.
I noticed that during the deployment process some http requests failed.
Occasionally, the server responded with an unfriendly error page, because nginx was not able to handle the request.
I also confirmed the errors by looking into the nginx error log. This was the error in /var/log/nginx/site-error.log.
The cause of these errors was that after every deployment, Envoyer was configured to reload php-fpm in order to reset the php cache (opcache).
Although the downtime was small, it was still a pain in the ass because we wanted truly zero downtime deployments and offer an excellent user experience to our users.
Because of this small downtime, we were conservative with the number of deploys per day. For example we avoided deployments during high server load for example and this was creating bottlenecks in our product development process.
Luckily, reloading php-fpm is not the only way to reset the opcache. There is a php function opcache_reset() that resets the cache but there is a catch: This function has to be executed from the php-fpm process (nginx) and not the command line.
This means that if you just run the function inside artisan, it won't work.
However thanks to the open source Cachetool command, we are able to reset the cache from the command line! I presume this tool makes an http call behind the scenes that resets the opcache.
We can create the following script and execute it once on our web server:
After installing, we execute as final step the command below to reset the opcache inside our deployment process.
Also, do not forget to stop the execution of php-fpm reload causing the downtime!
That's how we converted an "Almost zero downtime deployment" to a Truly zero downtime deployment with PHP!