Project

General

Profile

Lighty + Runit --> (almost) uninterruptible service :)

I had some problem with lighty's stability in the past so I ended up using a simple supervisor written in shell.
I didn't need it much for a long time now, but I thought runit would be a more elegant and robust solution than a shellscript + cron.

So here is how I got it working on Debian SID for a quick test:

  1. Install the wanted components

wajig install lighttpd
wajig install runit
This takes care of the basic config of both sw.
  1. Creating the service directories and service scripts

#!ShellExample
# mkdir -p /etc/sv/lighttpd/log/
# cat <<EOF >/etc/sv/lighttpd/run
#!/bin/bash
exec lighttpd -D -f /etc/lighttpd/lighttpd.conf 2>&1
EOF
#
# cat <<EOF >/etc/sv/lighttpd/log/run
#!/bin/bash
exec chpst -u nobody svlogd -tt /var/log/SV/
EOF
#
# chmod +x /etc/sv/lighttpd/run /etc/sv/lighttpd/log/run

  1. Setting up the log dir

#!ShellExample
# mkdir -p /var/log/SV
# chown nobody /var/log/SV
  1. Notifying runit about the new service and removing it from init's control

#!ShellExample
# ln -s /etc/sv/lighttpd/ /var/service/
# update-rc.d -f lighttpd remove
 Removing any system startup links for /etc/init.d/lighttpd ...
   /etc/rc0.d/K20lighttpd
   /etc/rc1.d/K20lighttpd
   /etc/rc2.d/S20lighttpd
   /etc/rc3.d/S20lighttpd
   /etc/rc4.d/S20lighttpd
   /etc/rc5.d/S20lighttpd
   /etc/rc6.d/K20lighttpd
  1. Checking status

#!ShellExample
# sv status lighttpd
run: lighttpd: (pid 4979) 19s; run: log: (pid 4606) 18s
#

Notes: Logging will be ok for a single service this way but may be problematic if you have several processes logging to the same directory.
I haven't tried it so I wouldn't know :)

It would have been nice to make it log the problems of lighty's startup over syslog but I couldn't get it working.
The line below should have taken care of it but it didn't work as expected for me. YMMV.


#!ShellExample
$ echo "U127.0.0.1" > /var/log/SV/config

Logging to file & startup errors to syslog

Another way to take care of logging is by configuring lighty to log errors to a file (error.log) and redirect startup errors (stderr) to syslog.


#!ShellExample
# cat <<EOF >/etc/sv/lighttpd/log/run
#!/bin/sh
exec >/dev/null
exec 2>&1
exec chpst \
        -unobody \
    \
    logger -d -p daemon.err -t lighttpd
EOF

If we want error.log to be handled by a svlogd process, we could start it from lighty, if only it supported that feature. ;)
(see #822)

Graceful restart with runit

This is possible with the help of a tiny (signal)wrapper, which:

- forwards SIGINT (and exits immediately for quick restart, lighttpd detaches and finishes in background)

- translates SIGTERM to SIGINT (and waits for graceful shutdown)

NOTE: fastcgi sockets must be named uniquely for each lighttpd process, otherwise the old (gracefully finishing) and new (starting up to handle new requests) lighty will argue over sockets. Simply insert var.PID into socket name. (This requires fastcgi processes to be started by lighttpd.)
(This requirement for graceful restart is not runit specific.)

Compile:


#!ShellExample
$ gcc -o sigintwrap sigintwrap.c

Use:


#!ShellExample
# cat <<EOF >/etc/sv/lighttpd/run
#!/bin/sh
exec sigintwrap lighttpd -D -f /etc/lighttpd/lighttpd.conf 2>&1
EOF