Back to Course |
Practical Laravel Queues on Live Server

Laravel Forge and Queues

As we explored the manual setup, in this lesson I will show you that there's a more convenient way to set up queues a lot faster.

Laravel Forge provides us with a convenient UI and helps us set up Queue Workers or Horizon daemon without having to scratch heads on how to configure supervisor.

1. Creating A Queue Worker

  1. You can create a new queue worker within the site's management dashboard. The "New Worker" form is a wrapper around the Laravel queue feature.

When creating a new queue worker, you can choose configuration options as we did in the command line or in the supervisor configuration. The configuration will be used when executing the queue worker.

Forge New Worker

⚠️ You should ensure that the value of Graceful Shutdown Seconds is greater than the Maximum Seconds Per Job. Otherwise, Supervisor may kill the job before it is finished processing.

  1. After creating a new worker the list with the most important settings will be displayed, so you can have a good overview of your queues and their settings.

Forge Workers List

We can inspect what really happened behind the scenes, after logging in to the server we can check what config for the supervisor was generated on the server:

/etc/supervisor/conf.d/worker-529763.conf

[program:worker-529763]
command=php8.1 /home/forge/example.org/artisan queue:listen redis --sleep=1 --quiet --timeout=30 --delay=3 --tries=3 --queue="default"
 
process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=forge
numprocs=10
stopwaitsecs=30
stdout_logfile=/home/forge/.forge/worker-529763.log
  1. Next, add the $FORGE_PHP artisan horizon:terminate Artisan command to the end of your site's deployment script.

Forge Queue Restart

Default deployment script with added queue:restart command looks like this:

cd /home/forge/example.org
git pull origin $FORGE_SITE_BRANCH
 
$FORGE_COMPOSER install --no-dev --no-interaction --prefer-dist --optimize-autoloader
 
( flock -w 10 9 || exit 1
echo 'Restarting FPM...'; sudo -S service $FORGE_PHP_FPM reload ) 9>/tmp/fpmlock
 
if [ -f artisan ]; then
$FORGE_PHP artisan migrate --force
fi
 
$FORGE_PHP artisan queue:restart

We need to restart the queue worker for code changes to take an effect after deployment.

2. Laravel Horizon

If your Laravel application is using Laravel Horizon, you should not set up queue workers as described above. Instead, you may enable Horizon on Forge using Forge's "daemon" feature.

  1. First, create a server daemon that executes the php8.1 artisan horizon Artisan command from your site's root directory.

Forge Create Horizon Daemon

It is important to note that the number of processes is set to 1 because child workers are managed by Horizon itself in the config/horizon.php file. This allows us to set up a daemon for Horizon once, and push changes by directly updating the configuration in the source code.

⚠️ You should ensure that the value of Stop Seconds is greater than the number of seconds consumed by your longest-running job. Otherwise, Supervisor may kill the job before it is finished processing.

  1. After creating a new daemon the list with supervisioned commands will be shown.

Forge Active Daemons

By logging into the server we can review the configuration that was created for the supervisor on the server:

/etc/supervisor/conf.d/daemon-736205.conf

[program:daemon-736205]
directory=/home/forge/example.org/
command=php8.1 artisan horizon
 
process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
user=forge
numprocs=1
startsecs=1
redirect_stderr=true
stdout_logfile=/home/forge/.forge/daemon-736205.log
stopwaitsecs=30
stopsignal=SIGTERM
stopasgroup=true
killasgroup=true
  1. Next, add the php artisan $FORGE_PHP artisan horizon:terminate Artisan command to your site's deployment script.

Forge Horizon Terminate

cd /home/forge/example.org
git pull origin $FORGE_SITE_BRANCH
 
$FORGE_COMPOSER install --no-dev --no-interaction --prefer-dist --optimize-autoloader
 
( flock -w 10 9 || exit 1
echo 'Restarting FPM...'; sudo -S service $FORGE_PHP_FPM reload ) 9>/tmp/fpmlock
 
if [ -f artisan ]; then
$FORGE_PHP artisan migrate --force
fi
 
$FORGE_PHP artisan horizon:terminate

horizon:terminate lets Horizon finish currently working jobs and ends the process. The supervisor runs horizon again for us like in the first case. This is important for code changes to take an effect.