Background Jobs & Queues

Supervisord: Running Python, PHP, and Node Processes on a VPS

By Domain India Team · DomainIndia SupportPublished 8 min read
Knowledge base article
Contents (9 sections)

Background workers, such as Laravel queue workers, Celery workers or a custom Python daemon, have to keep running after you log out, restart when they crash and start again after a reboot. Supervisor (its daemon is supervisord) is a small, language-neutral process manager that does exactly that on a Linux server you control. This guide covers installing it, writing a program config, running several workers, handling secrets and logs, and fixing the common problems.

Key takeaways

Install Supervisor from your distribution's packages, write one config file per program with command, directory, user, autostart, autorestart and log settings, then run supervisorctl reread and supervisorctl update. Always run workers as a non-root user, set stopwaitsecs longer than your longest job, and cap log sizes. Supervisor needs root to install and is for your own VPS, not shared hosting.

This guide is for your own server

Supervisor needs root access and long-running processes, so it runs on a VPS or other server you manage. It can't be installed on shared hosting. The options for background jobs on Domain India are in section 9.

1. Why use a process manager?

A worker started with python worker.py & stops when you close the SSH session, when the server reboots or when it crashes. A process manager owns the process's lifecycle: it starts it at boot, restarts it on failure, captures its output to log files and gives you one command to start, stop and inspect everything.

Supervisor's strengths are simple INI-style configs, running several copies of one worker (numprocs), and grouping related programs. The Laravel documentation uses it for queue workers.

2. Install Supervisor

Ubuntu and Debian:

bash
sudo apt update
sudo apt install supervisor
sudo systemctl enable --now supervisor

AlmaLinux, Rocky Linux and other RHEL-family systems (the package is in EPEL):

bash
sudo dnf install epel-release
sudo dnf install supervisor
sudo systemctl enable --now supervisord

Program configs go in /etc/supervisor/conf.d/*.conf on Debian and Ubuntu, and /etc/supervisord.d/*.ini on RHEL-family systems. Use one file per application.

3. Your first program: a Laravel queue worker

ini
; /etc/supervisor/conf.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php /home/myapp/current/artisan queue:work --sleep=3 --tries=3 --max-time=3600
directory=/home/myapp/current
user=myapp
numprocs=2
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stopwaitsecs=3600
redirect_stderr=true
stdout_logfile=/var/log/myapp/worker_%(process_num)02d.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
SettingWhat it does
commandThe exact command, with absolute paths; Supervisor runs with a minimal PATH
directoryThe working folder, so relative paths in your app resolve
userThe non-root account the worker runs as
numprocs and process_nameHow many copies run, and a unique name for each
autorestart=trueRestarts the process whenever it exits
stopasgroup and killasgroupStops child processes too, not only the parent
stopwaitsecsHow long to wait after SIGTERM before SIGKILL; set it longer than your longest job
stdout_logfile_maxbytes and _backupsRotates logs so they can't fill the disk

--max-time=3600 makes the worker exit cleanly every hour so that Supervisor starts a fresh one, which contains slow memory leaks. Create the log folder first (sudo mkdir -p /var/log/myapp && sudo chown myapp: /var/log/myapp).

4. Apply and control programs

  1. Load new or changed configs.
    Run sudo supervisorctl reread, which finds the changes.
  2. Apply them.
    Run sudo supervisorctl update, which starts, stops or restarts only the programs whose config changed.
  3. Check status.
    sudo supervisorctl status lists every process with RUNNING, STARTING, BACKOFF or FATAL.
  4. Control a program.
    sudo supervisorctl restart 'laravel-worker:*' restarts every copy; use start and stop the same way.
  5. Read output.
    sudo supervisorctl tail -f laravel-worker:laravel-worker_00 follows one process's log; add stderr for the error stream if you didn't redirect it.

Quote 'name:*' so the shell doesn't expand the asterisk. supervisorctl reload restarts Supervisor itself and therefore every program, so use reread and update for routine changes. After a code deploy, php artisan queue:restart tells Laravel workers to finish their current job and exit, and Supervisor starts them again on the new code.

When an app has several worker types, group them so that you can restart them together:

ini
[program:emails]
command=/usr/bin/php /home/myapp/current/artisan queue:work --queue=emails
directory=/home/myapp/current
user=myapp
autostart=true
autorestart=true
stdout_logfile=/var/log/myapp/emails.log

[program:payments]
command=/usr/bin/php /home/myapp/current/artisan queue:work --queue=payments --timeout=300
directory=/home/myapp/current
user=myapp
autostart=true
autorestart=true
stopwaitsecs=360
stdout_logfile=/var/log/myapp/payments.log

[group:myapp]
programs=emails,payments

Then sudo supervisorctl restart 'myapp:*' restarts both.

6. Other languages

Python (Celery):

ini
[program:celery]
command=/home/myapp/venv/bin/celery -A myapp worker --loglevel=INFO --concurrency=4
directory=/home/myapp
user=myapp
autostart=true
autorestart=true
stopwaitsecs=600
stopasgroup=true
killasgroup=true
stdout_logfile=/var/log/myapp/celery.log

Let Celery handle concurrency with --concurrency and keep numprocs=1; don't multiply both. Use the virtualenv's own binary so the right packages load.

A long-running script that must stay up: add startsecs=10 and startretries=3. A process that dies within 10 seconds of starting counts as a failed start, and after three such failures Supervisor marks it FATAL instead of restarting it for ever.

Node.js: Supervisor works, but PM2 adds cluster mode and zero-downtime reloads. See PM2 for Node.js process management.

7. Secrets and security

  • Never run workers as root. Create a dedicated user (sudo useradd --system --create-home myapp), and give it only the folders it needs.
  • Keep secrets out of world-readable configs. Files in the Supervisor config folder are normally readable by every user on the server, so an environment=DB_PASSWORD="…" line there exposes the password to all local accounts. Let the application read its own .env file (Laravel and most frameworks do), owned by the worker user with chmod 600. If you must put secrets in the Supervisor config, restrict that file to root with chmod 600.
  • Leave the web interface off, or bind it to 127.0.0.1 with a strong password and reach it through an SSH tunnel. Never expose it to the internet.

8. Troubleshooting

SymptomLikely causeFix
Status BACKOFF or FATALThe program exits within startsecsRead its log; check paths, permissions, missing env vars or packages
Jobs killed mid-run on restartstopwaitsecs shorter than the jobRaise it above your longest job's run time
Config change not appliedreread run without updateRun supervisorctl update
"unix:///var/run/supervisor.sock no such file"The daemon isn't runningsudo systemctl start supervisor (or supervisord)
Disk filling with logsLog limits too high or missingSet stdout_logfile_maxbytes and stdout_logfile_backups
Worker runs old code after deployLong-running workers keep code in memoryphp artisan queue:restart, or restart the group

9. Where Domain India fits

  • VPS: you get full root access, so Supervisor, Redis and any queue backend install normally. A VPS is self-managed: you install, update and monitor it yourself. See VPS hosting.
  • Shared hosting (cPanel, DirectAdmin): Supervisor and other long-running processes aren't available. For Laravel queues, run a cron job that processes the queue and exits, for example php artisan queue:work --stop-when-empty; test it on your plan first. Cron jobs on shared hosting run at most every 4 minutes. There is no Redis on shared plans, so use the database queue driver.
  • App Platform: for Node.js and Dockerfile-based apps where we run the servers. Whether a separate background worker process suits your app is worth checking with support before you rely on it. See Getting started with App Platform.

For choosing a queue system, see BullMQ, Sidekiq and Celery compared.

Can I run Supervisor on shared hosting?

No. Supervisor needs root access to install and runs long-lived processes, which shared hosting doesn't allow. Use a VPS, or on shared hosting run queue jobs from cron with a command that exits when the queue is empty.

What is the difference between supervisorctl reread, update and reload?

reread finds new or changed config files, update applies them and restarts only the programs that changed, and reload restarts Supervisor itself along with every program. Use reread followed by update for routine changes.

Why is my Supervisor program in BACKOFF or FATAL?

It keeps exiting within startsecs of starting. Read the program's log with supervisorctl tail, and check the command path, file permissions, the working directory and any missing environment variables or packages.

How long should stopwaitsecs be?

Longer than your longest job. When a worker is stopped, Supervisor sends SIGTERM and waits stopwaitsecs before killing it, so a short value cuts off jobs that are still running.

Should I use Supervisor or systemd?

Both work. Supervisor is simpler for running several copies of a worker and grouping them, and it is what the Laravel documentation uses. systemd is built into the OS and suits single services. Use whichever you will maintain, and keep each worker managed by only one of them.

How do I stop Supervisor logs from filling the disk?

Set stdout_logfile_maxbytes and stdout_logfile_backups in each program, for example 10MB and 5, which caps that log at about 60 MB. Give each program, and each copy, its own log file.

Ready to run workers on your own server? Compare plans on VPS hosting, or read Getting started with App Platform if you'd rather not manage a server.

Run your workers on a VPS

Full root access to install Supervisor, Redis and any queue backend you need.

See VPS plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Supervisor (supervisord) Guide for Workers on a VPS