September 27, 2021
I just set up Laravel Horizon to manage our queue in a multi-server environment. The documentation is a little thin in this area but the ultimate solution is pretty simple.
We have a load balancer, two web servers, a database server, and a queue server. The database server runs Redis and the web servers and queue server are all configured to connect to it. We only want to process queues on our dedicated queue server - not on our web servers.
Follow the documentation to get Horizon dependencies and config into your project.
app/Providers/HorizonServiceProvider.php
includes some helpful features like notifications and gating access on production. I used our auth()->user()->isSuperAdmin()
method and you'll probably have something similar in your project.
I did not need to make any changes.
If you are running just one server, this is pretty trivial. This is where things got uncertain for me, but it's not very complicated!
On your queue worker, add a daemon to run artisan horizon
. If your site name is the default 'app-worker', this command will be
1php /home/forge/app-worker/current/artisan horizon
This will ensure that Horizon is always working on that queue server.
On your web servers, add nothing. You will not run any jobs on your web servers, which is how I prefer to run things.
Add the following deploy hook:
1cd {{release}}2 3php artisan horizon:purge4php artisan horizon:terminate
this should only run on your queue server so ensure you just have that server checked in the On Server section. Drag this deploy hook after Activate New Release.
This deploy hook will force Horizon to reload and pick up any recent code changes. Since you set up a daemon previously, that process will be killed and then restarted automatically.
Run a fresh deploy at Envoyer, then visit https://your-app-domain.com/horizon to verify that the admin panel is running properly.