GICT knowledge base
Understanding Supervisor on Linux: A Practical Introduction
Published
You know that sinking feeling when your web application crashes at 3 AM and you’re fast asleep? I’ve been there. After years of managing Linux servers, I can tell you that babysitting processes manually is exhausting and completely unnecessary.
That’s exactly why I fell in love with Supervisor. It’s like having a reliable system administrator who never sleeps, never takes breaks, and always keeps your applications running smoothly.
What Actually is Supervisor Linux?
Let me break this down in simple terms. The supervisor is basically a watchdog for your programs. Imagine you have a friend who promises to restart your computer game every time it crashes – that’s essentially what Supervisor does for your server applications.
I remember when I first discovered Supervisor during a particularly frustrating week where my Flask application kept dying randomly. Within an hour of setting it up, I never had to manually restart that app again.
Here’s what makes Supervisor awesome:
- Your applications restart automatically when they crash (no more 3 AM wake-up calls).
- You can control everything from one place instead of juggling multiple terminal windows.
- Detailed logs tell you exactly what’s happening with your processes.
- The configuration is surprisingly straightforward – no PhD in system administration required.
Most people use Supervisor for web applications, background jobs, API services, and basically anything that needs to run continuously without human intervention.
Getting Your System Ready
Before we dive in, let’s make sure you have everything sorted. I learned this the hard way after spending two hours troubleshooting an installation that failed because I skipped the basics.
You’ll need any recent Linux distribution – Ubuntu, CentOS, Debian, whatever you prefer. Python should already be installed (and it probably is). Basic command line skills help, but honestly, you can copy-paste most of what we’ll do here.
I always recommend starting with Ubuntu if you’re new to this. It just works without the headaches.
Installing Supervisor – The Right Way
I’ve tried every installation method, and here’s what actually works reliably:
The Package Manager Route (My Recommendation)
If you’re on Ubuntu or Debian, this is dead simple:
sudo apt update
sudo apt install supervisor
For CentOS folks:
sudo yum install epel-release
sudo yum install supervisor
Fedora users get this:
sudo dnf install supervisor
Alternative: Python pip Method
Sometimes the package manager version is outdated. In those cases:
sudo pip install supervisor
Make Sure Everything Worked
Run these commands to verify:
supervisord --version
supervisorctl --version
If you see version numbers, you’re golden. Now let’s get the service running:
sudo systemctl enable supervisor
sudo systemctl start supervisor
sudo systemctl status supervisor
That last command should show “active (running)” in green. If it doesn’t, something went wrong during installation.
Understanding Supervisor Configuration
This part confused me initially because the configuration looks intimidating. But once you understand the structure, it’s actually quite logical.
The main config file lives at /etc/supervisor/supervisord.conf. Think of it as the master control panel. Here’s what a basic setup looks like:
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700
[supervisord]
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log/supervisor
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[include]
files = /etc/supervisor/conf.d/*.conf
That last line is crucial – it tells Supervisor to load all configuration files from the conf.d directory. This is where we’ll put our application configs.
Your First Real Application Setup
Let’s get practical. I’ll show you how I typically set up a Python web application, because that’s probably what you’re here for.
Creating the Configuration File
Create a new file at /etc/supervisor/conf.d/myapp.conf:
[program:myapp]
command=/usr/bin/python3 /path/to/your/app.py
directory=/path/to/your/
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/myapp.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=5
What Each Setting Actually Does
Let me explain these settings because the documentation can be pretty dry:
- command – This is exactly what you’d type in the terminal to run your app
- directory – Where Supervisor should “cd” to before running the command
- user – Which system user should run this process (never use root unless absolutely necessary)
- autostart – Start this when Supervisor starts up
- autorestart – Restart if the process dies unexpectedly
- redirect_stderr – Combine error messages with regular output
- stdout_logfile – Where to save the output
Actually Starting Your Application
Now comes the moment of truth:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start myapp
If everything worked, you should see “myapp: started”. If not, don’t panic – we’ll troubleshoot in a minute.
Commands You’ll Actually Use Daily
After managing dozens of applications with Supervisor, these are the commands I use constantly:
Checking What’s Running
sudo supervisorctl status
This shows you everything and whether it’s running, stopped, or having issues.
Starting and Stopping Stuff
# Start one specific program
sudo supervisorctl start myapp
# Stop one program
sudo supervisorctl stop myapp
# Restart (stop then start)
sudo supervisorctl restart myapp
# Nuclear option - restart everything
sudo supervisorctl restart all
Watching Logs in Real Time
This is incredibly useful for debugging:
sudo supervisorctl tail myapp
Add -f to follow the logs as they update, just like tail -f.
The Interactive Mode
Sometimes I just want to poke around without typing “supervisorctl” over and over:
sudo supervisorctl
This drops you into an interactive shell where you can run commands directly.
Managing Multiple Applications Like a Pro
Once you get comfortable with single applications, you’ll want to organize things better. Groups are your friend here.
Here’s how I typically organize a web project with multiple components:
[group:webstack]
programs=webapp,worker,scheduler
[program:webapp]
command=/var/www/myproject/venv/bin/gunicorn app:application
directory=/var/www/myproject/
autostart=true
autorestart=true
user=www-data
[program:worker]
command=/var/www/myproject/venv/bin/celery -A app worker
directory=/var/www/myproject/
autostart=true
autorestart=true
user=www-data
[program:scheduler]
command=/var/www/myproject/venv/bin/celery -A app beat
directory=/var/www/myproject/
autostart=true
autorestart=true
user=www-data
Now I can control the entire stack with group commands:
# Start everything
sudo supervisorctl start webstack:*
# Check status of the whole group
sudo supervisorctl status webstack:*
Startup Priority
Sometimes order matters. Maybe your database needs to start before your web application:
[program:database]
priority=100
command=/usr/local/bin/start-database.sh
[program:webapp]
priority=200
command=/usr/bin/python3 app.py
Lower numbers start first, higher numbers start later.
Logging That Actually Helps
I learned about proper logging the hard way after spending hours debugging an issue with no useful logs. Here’s what works:
Separate Error and Output Logs
[program:myapp]
command=/usr/bin/python3 /path/to/app.py
stdout_logfile=/var/log/supervisor/myapp.out.log
stderr_logfile=/var/log/supervisor/myapp.err.log
stdout_logfile_maxbytes=50MB
stderr_logfile_maxbytes=50MB
stdout_logfile_backups=10
stderr_logfile_backups=10
Log Rotation Settings
Those maxbytes and backups settings prevent your logs from eating up disk space. When a log file reaches 50MB, Supervisor creates a new one and keeps the last 10 old files around.
If you prefer using logrotate (which I do), set:
stdout_logfile_maxbytes=0
This disables Supervisor’s built-in rotation.
When Things Go Wrong (And They Will)
I’ve hit pretty much every Supervisor error you can imagine. Here are the most common ones and how to fix them:
“No Such File” Socket Error
This usually means Supervisor isn’t running:
sudo systemctl start supervisor
If that doesn’t work, start it manually:
sudo supervisord -c /etc/supervisor/supervisord.conf
Program Won’t Start
First, check what’s actually happening:
sudo supervisorctl tail myapp stderr
Nine times out of ten, it’s one of these issues:
- The command path is wrong – double-check your paths
- Permission problems – make sure the user can actually run the program
- Missing dependencies – your app might need libraries that aren’t installed
- Environment variables – your app might expect certain environment variables
Permission Headaches
This happens a lot with web applications:
# Check current ownership
ls -la /path/to/your/app.py
# Fix ownership if needed
sudo chown www-data:www-data /path/to/your/app.py
sudo chmod +x /path/to/your/app.py
Infinite Restart Loop
If your program keeps crashing and restarting, add these limits:
startretries=3
startsecs=10
exitcodes=0,2
This tells the supervisor to give up after 3 restart attempts and only consider the program “started” if it runs for at least 10 seconds.
Advanced Features That Actually Matter
Once you’re comfortable with the basics, these features can make your life significantly easier:
Web Interface
This is honestly pretty cool. Add this to your main config:
[inet_http_server]
port=127.0.0.1:9001
username=admin
password=your-secure-password
Now you can monitor everything through a web browser at http://localhost:9001. Just don’t expose this to the internet without proper security.
Environment Variables
Your applications probably need environment variables:
[program:myapp]
command=/usr/bin/python3 app.py
environment=PATH="/usr/local/bin",DATABASE_URL="postgresql://user:pass@localhost/db",DEBUG="false"
Working with systemd
On modern Linux systems, you want Supervisor to start automatically with the system. Most package installations handle this, but if you installed via pip, create this file at /etc/systemd/system/supervisor.service:
[Unit]
Description=Supervisor process control system
After=network.target
[Service]
ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisor/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl shutdown
ExecReload=/usr/local/bin/supervisorctl reload
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
Supervisor vs Everything Else
People always ask me when to use Supervisor versus other tools. Here’s my honest take:
Supervisor vs systemd
I use systemd for system-level services (like nginx, postgresql) and Supervisor for application-level processes. systemd is more powerful but also more complex. Supervisor’s configuration is much easier to understand and modify.
If you’re managing a web application with multiple components, Supervisor is usually the better choice.
Supervisor vs PM2
PM2 is fantastic if you’re only running Node.js applications. It has built-in clustering, zero-downtime deployments, and other Node-specific features.
But if you’re running mixed applications (Python + Node.js + whatever), Supervisor is more universal.
Supervisor vs Docker
This isn’t really an either-or situation. I often use Supervisor inside Docker containers to manage multiple processes within a single container, though that’s somewhat controversial in the Docker community.
Real Examples from My Projects
Let me show you some real configurations I use in production:
Django + Gunicorn
[program:django-production]
command=/var/www/mysite/venv/bin/gunicorn mysite.wsgi:application --bind 127.0.0.1:8000 --workers 4
directory=/var/www/mysite/
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/django.log
environment=PATH="/var/www/mysite/venv/bin",DJANGO_SETTINGS_MODULE="mysite.settings.production"
Background Worker with Celery
[program:celery-worker]
command=/var/www/myapp/venv/bin/celery -A myapp worker -l info --concurrency=4
directory=/var/www/myapp/
user=celery
numprocs=1
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/celery-worker.log
stopwaitsecs=600
killasgroup=true
priority=998
That stopwaitsecs=600 is important for Celery – it gives running tasks time to finish before killing the process.
Node.js API Server
[program:api-server]
command=/usr/bin/node server.js
directory=/var/www/api/
user=nodejs
autostart=true
autorestart=true
environment=NODE_ENV=production,PORT=3000,DATABASE_URL="mongodb://localhost:27017/mydb"
stdout_logfile=/var/log/supervisor/api-server.log
Security and Performance Tips
After running Supervisor in production for years, here are the lessons I’ve learned:
Security First
Never run processes as root unless absolutely necessary. Create dedicated users for your applications:
sudo adduser --system --group --no-create-home webapp
If you enable the web interface, bind it to localhost only and use strong passwords. Better yet, set up proper authentication with a reverse proxy.
Performance Considerations
- Don’t go crazy with restart attempts. If something is failing repeatedly, you want to know about it, not have the supervisor hide the problem by constantly restarting.
- Set reasonable log file sizes. I typically use 20-50MB with 5-10 backups. Adjust based on how verbose your applications are.
- Monitor your processes. The supervisor tells you if something is running, but it doesn’t tell you if it’s working correctly. Use proper application monitoring for that.
Where to Go from Here
You now know enough Supervisor to handle most real-world scenarios. My advice? Start simple. Pick one application you’re currently running manually and set it up with Supervisor. Once you’re comfortable, gradually add more complexity.
The official Supervisor documentation is actually quite good once you understand the basics. The community is helpful too – most common problems have been solved before.
Some things to explore next:
- Set up event listeners for email notifications when processes crash
- Integrate with monitoring systems like Nagios or Prometheus
- Learn about Supervisor’s XML-RPC interface for programmatic control
- Experiment with the various restart strategies for different types of applications
Final Thoughts
Supervisor isn’t the fanciest tool in the world, but it’s reliable, well-documented, and solves a real problem elegantly. I’ve been using it for years and it just works.
The best part? Once you set it up properly, you can almost forget about it. Your applications will keep running, logs will be organized, and you’ll sleep better knowing your services are being watched.
Start with something simple, get it working, then gradually build up your configuration. Before you know it, you’ll wonder how you ever managed servers without it.
Related guides
How to Restrict an SSH Key to One Command
Restrict an SSH key to one command with authorized_keys options. Protect the command and check that unwanted shell and forwarding access are denied.
Linux and CommandsSelf-Hosted Video Processing With FFmpeg: A Practical Guide
Learn how to self-host video processing on a VPS using FFmpeg, with practical commands for conversion, compression, thumbnails, and automated workflows.
Linux and CommandsHow to use nohup: Commands in Linux That Survive Terminal Closes
Keep commands running after you close the terminal. nohup examples with wget, Python, rsync, and Docker on any VPS.
Linux and CommandsHow to Fix “Too Many Open Files” Error on Linux Servers
Learn how to fix the "Too Many Open Files" error on Linux servers by understanding file descriptors, adjusting limits, and diagnosing leaks effectively.
