Using Supervisor on macOS
When I’m working on a project, I often need to run a number of processes, e.g. a frontend app, several backend services, maybe a redis server etc. Instead of running them in Docker containers, or in separate terminal windows, I like to use Supervisor. Supervisor is a process control system on UNIX-like OSes, and is easy to use on macOS.
Installation
The simplest option is to use pip:
pip3 install supervisor
Other options for installation are available here.
Creating a Configuration File
You can create a sample configuration file using echo_supervisord_conf
.
echo_supervisord_conf > /path/to/supervisord.conf
Customize the file as appropriate. I leave the default sections as-is, just add my programs:
[program:redis-server]
command=/path/to/redis-server
autostart=false
autorestart=true
stdout_logfile=/path/to/logs/redis-server.log
stderr_logfile=/path/to/logs/redis-server.err.log
Finally, I like to create a symbolic link in /etc/
so supervisor can automatically find the file. This is not required, it just saves me from having to type the full path every time.
sudo ln -s /path/to/supervisord.conf /etc/supervisord.conf
Running supervisord
Now we are ready to start the server:
supervisord
If you didn’t create a symlink in one of the default paths where supervisord searches for the config file, you can also specify the config path on the command line:
supervisord -c /path/to/supervisord.conf
Running supervisorctl
You interact with supervisord using supervisorctl
:
$ supervisorctl status
redis-server STOPPED Not started
Or if the config file is not in a standard location:
$ supervisorctl -c /path/to/supervisord.conf status
redis-server STOPPED Not started
Managing the processes
You can a variety of commands with supervisorctl to manage the processes, including start
, stop
, restart
, status
and reload
. To get a full list of commands, type:
supervisorctl help
Creating an alias
Finally, I create a helper function to save myself a few keystrokes every time I need to start, stop or restart a process. Something like this:
sup() {
if (( $# == 0 )) then
cd /path/to/logs
fi
case "$1" in
"logs") cd /path/to/logs
;;
"status") supervisorctl status
;;
"start")
case "$2" in
"all")
supervisorctl start redis-server
;;
"redis")
supervisorctl start redis-server
;;
*) supervisorctl start $2
;;
esac
;;
"stop") ;&
"restart")
case "$2" in
"redis")
supervisorctl $1 redis-server
;;
*) supervisorctl $1 $2
;;
esac
esac
}
Now I can type:
sup status
sup start redis
sup stop redis
sup restart redis
That’s it!