Back to Course |
Practical Laravel Queues on Live Server

Supervisor Configuration

In production, we need a way to keep our queue:work processes running. A queue:work process may stop running for a variety of reasons, such as an exceeded worker timeout or the execution of the queue:restart command.

For this reason, we need to configure a process monitor that can detect when processes like queue:work stop running and restart them. Supervisor is a process monitor commonly used in Linux environments and we will discuss how to configure it.

This chapter will cover Debian-based (Ubuntu) and RedHat-based (Fedora) Linux distributions.

Installing Supervisor

To install Supervisor you may use the following command:

Ubuntu

sudo apt-get install supervisor

Fedora

sudo dnf install supervisor

Configuring supervisor

Make sure the Supervisor itself is started during system boot and start it if it is not started by default after installation.

sudo systemctl enable supervisor
sudo systemctl start supervisor

Now let's create a new configuration file for the Supervisor. Different distributions have a bit different configuration locations.

Ubuntu

On Ubuntu Supervisor configurations follows this mask:

/etc/supervisor/conf.d/*.conf

Create /etc/supervisor/conf.d/laravel-worker.conf file.

Fedora

On Fedora Supervisor configurations follows this mask:

/etc/supervisord.d/*.ini

Create /etc/supervisord.d/laravel-worker.ini file.

Configuration file contents

While having different Supervisor configuration locations on both distros contents of the configuration itself doesn't differ since it is the same service.

[program:laravel-worker]
directory=/home/web/laravel-queues
command=php artisan queue:work --sleep=1 --tries=3 --max-time=3600
 
process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=web
numprocs=8
redirect_stderr=true
stdout_logfile=/home/web/.supervisor/laravel-worker.log
stopwaitsecs=3600

You may rename the process to something else by changing [program:laravel-worker] to [program:my-meaningful-name].

Also, you should update the command, user, numprocs, and stdout_logfile flags to match your environment and requirements.

Now let's run through all the settings:

  • directory - a file path representing a directory to which supervisord should temporarily chdir before exec'ing the child
  • command - actual command to launch queue workers including full path to your project and additional flags for workers
  • process_name - this flag defines how your processes are displayed when you run supervisorctl status command
  • autostart - If true, this program (command) will start automatically when the supervisord is started
  • autorestart - Specifies if supervisord should automatically restart a process if it exits when it is in the RUNNING state.
  • stopasgroup - If true, the flag causes the Supervisor to send the stop signal to the whole process group. This is useful for programs that do not propagate stop signals to their children, leaving them orphaned.
  • killasgroup - If true, when resorting to SIGKILL to the program to terminate it send it to its whole process group instead, taking care of its children as well.
  • user - Instruct the supervisord to use this UNIX user account as the account which runs the program. Usually, you want to run command under the same user as your Laravel application runs.
  • numprocs - Supervisor will start as many instances of this program as named by numprocs.
  • redirect_stderr - If true, cause the process' STDERR output to be sent back to supervisord on its STDOUT file descriptor.
  • stdout_logfile - Put process output in this file. Since workers will be running in the background sometimes it is useful to have logs which you would usually see in the terminal when running queue:work manually.
  • stopwaitsecs - The number of seconds to wait for the OS to return a SIGCHLD to supervisord after the program has been sent a stopsignal. If this number of seconds elapses before the supervisord receives a SIGCHLD from the process, the supervisord will attempt to kill it with a final SIGKILL.

You should ensure that the value of stopwaitsecs is not less that the number of seconds consumed by your longest-running job. Otherwise, Supervisor may kill the job before it is finished processing.

Once the configuration file has been saved reload the daemon's configuration files without affecting currently running processes using the following command:

sudo supervisorctl reread

If reread was successful and no errors have been reported you can reread them but this time forcing updates to processes using this command:

sudo supervisorctl update

Alternatively, you can run the supervisorctl start program-name:* command to only start processes if it was read earlier:

sudo supervisorctl start laravel-worker:*

And then check what processes are running by Supervisor:

sudo supervisorctl status

Should give similar output depending on your configuration.

laravel-worker:laravel-worker_00 RUNNING pid 612470, uptime 0:00:22
laravel-worker:laravel-worker_01 RUNNING pid 612471, uptime 0:00:22
laravel-worker:laravel-worker_02 RUNNING pid 612472, uptime 0:00:22
laravel-worker:laravel-worker_03 RUNNING pid 612473, uptime 0:00:22
laravel-worker:laravel-worker_04 RUNNING pid 612474, uptime 0:00:22
laravel-worker:laravel-worker_05 RUNNING pid 612475, uptime 0:00:22
laravel-worker:laravel-worker_06 RUNNING pid 612476, uptime 0:00:22
laravel-worker:laravel-worker_07 RUNNING pid 612477, uptime 0:00:22

Now try registering a new user again on your laravel application, and the email should arrive in the testing inbox.

Before we move on to the next chapter we can stop these workers for now.

To do that run the supervisorctl stop program-name:* command. For example:

sudo supervisorctl stop laravel-worker:*
laravel-worker:laravel-worker_00: stopped
laravel-worker:laravel-worker_01: stopped
laravel-worker:laravel-worker_02: stopped
laravel-worker:laravel-worker_03: stopped
laravel-worker:laravel-worker_04: stopped
laravel-worker:laravel-worker_05: stopped
laravel-worker:laravel-worker_06: stopped
laravel-worker:laravel-worker_07: stopped