A supervisor's main task, is to start a specified process (in a specified environment), watch it running, and do something when it ends - usually based on the exit code.
From my experience, the environment setup can be a complex task (consult some config management for the required ports, actualize the config file from the central config management...), and this is where the most featureful supervisor (systemd, AFAIK) falls short:
- it can setup & manage the listening sockets, and pass it to your app (if it can accept it - not hard, just have to be ready for it),
- can set environment variables - but just with static values
- and can run preparation jobs - but just for 30 seconds!
and my biggest complaint against it is the strict, quite restricted format, where writing simple scripts is hard
- especially with those unhelpful "bad quoting" error messages.
This is where I feel another big disadvantage: debugging. I don't know a way to test the systemd service other than
start it, call systemctl status my.service
couple of times, maybe journalctl -f
in another window.
Runit is a very simple supervisor, composed by a handful programs, in the UNIX philosophy:
svlogd
logging daemon writes lines from its stdin into files in a specified directory, rotates & compresses & mails as defined in the "config" file in that directory.chpst
helps running yout program as the specified user, maybe holding a lock on the specified file, even setting the program's name as you wish.runsv
runs the "run" program (usually a shell script which sets up the environment, then execs your app), calls the "finish" (if exist) on exit, then restarts after a second sleep.sv
sends commands to runsv by writing one letter into thesupervise/ctl
file set SVDIR so you won't have to specify it tosv
:export SVDIR=/etc/service; sv restart caddy
will restart/etc/service/caddy
.runsvdir
watches a directory, and starts runsv on each subdirectory - so it can supervise multiple programs.
Comparing to systemd, it can't do the socket activation magic, but
- can set up complex environment - it's just the
run
shell script - can debug it easily: just call
./run
as yourrunsv
would!
Caddy is a very simply usable web server, so doesn't need too much, the simplest run
file can be:
#!/bin/sh
exec /usr/local/bin/caddy -conf=/etc/Caddyfile
And a more complex:
#!/bin/sh
exec chpst -b my-web-server -u www-data -L /var/run/caddy.lock \
/usr/local/bin/caddy -conf=/etc/Caddyfile
Sorry, Caddy is too simple to force writing some big fat setup script :)
Now I start runsvdir by my init daemon (upstart, systemd, OpenRC, SysV - what you have), and let runit do its job.