# How to use Laravel Queue Worker with Supervisor

# Why use Supervisor?

When developing Laravel Application, you will most probably make use of Queues or more specifically of the $ php artisan queue:work command, which enables you to queue jobs such as sending emails. This has the benefit to reduce loading times and also structures code better.

Running the command is easy on local, but when it comes to production deployment, example on a virtual machines with LEMP Stack, then you could encounter some problems. The biggest disadvantage is that the worker could running because something failed. Also the worker is not restarting if your have deployed changes.

There is the possibility to run $ nohup php artisan queue:work --daemon & as suggested here but comes with similar pitfalls as running the command solely. This is where it comes handy to use a process monitor or manager as Supervisor. A popular alternative with NodeJS would be PM2.

# Preassumptions

  1. Assuming that you have set up a virtual machine with LEMP Stack, preferrably on Ubuntu 18.04, served by Digital Ocean. Your user is not root but has root permissons.

  2. You have deployed your Laravel Application to the server and configured the webserver accordingly.

  3. You have configured your queue settings in your config/queue.php to use the database queue connection.

# Install & Configure Supervisor

1. Installation

To install on Ubuntu 18.04 just run:

$ sudo apt install supervisor

To check whether the installation was succesful, run $ service supervisor status and it will return output like this:

 Active: active (running) since Fri 2020-11-27 16:27:12 UTC; 19s ago

2. Adjust user permissions for Supervisor

For Supervisor being able to access the artisan command with sudo, we need to create a new user group and add the active user to it:

  $ sudo groupadd supervisor
  $ sudo usermod -a -G supervisor $USER

Then, adjust the main supervisor config file to have the necessary permission. For that open the main config file with an editor:

$ sudo nano /etc/supervisor/supervisord.conf

The content should be adjusted like this:

; supervisor config file

[unix_http_server]
file=/var/run/supervisor.sock   ; (the path to the socket file)
chmod=0770                       ; socket file mode (default 0700)
chown=root:supervisor

[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket

; The [include] section can just contain the "files" setting.  This
; setting can list multiple files (separated by whitespace or
; newlines).  It can also contain wildcards.  The filenames are
; interpreted as relative to this file.  Included files *cannot*
; include files themselves.

[include]
files = /etc/supervisor/conf.d/*.conf

Notice the change is the file mode ( chmod=0770 ) and the user group supervisor assigned to root ( chown=rott:supervisor )

After adjusting the main config you will need to restart the service:

$ sudo service supervisor restart

3. Add your program configuration file

To implement the actual Laravel Queue Worker, all you need to do is to create a new program configuration file which should be located in /etc/supervisor/conf.d Create it with nano:

  $ sudo nano /etc/supervisor/conf.d/laravel-worker.conf

And it will give output like this:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=sudo php /var/www/laravel/artisan queue:work --tries=3 --daemon
user=root
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/laravel/storage/logs/test.log

The command actually calls the Laravel queue worker.

4. Reset supervisor to apply changes

Finally run the following commands to make the changes take effect:

  $ supervisorctl reread
  $ supervisorctl update

To check running status, run:

  $ supervisorctl status

The output will be like this:

laravel-worker:queue_00                   RUNNING   pid 2093, uptime 0:01:46