fcgiwrap and s6


This site is powered by werc, which is a Plan 9 rc(1) shell script, which runs as a CGI executable. HTTP is served by nginx, which doesn't support CGI out of the box, so I'm also using fcgiwrap(8) to run CGI programs in response to FastCGI requests.

By default on Debian (and probably other distributions), fcgiwrap(8) is started using systemd's socket activation. Out of curiosity, I wanted to make this work using s6's IPC tools seeing as I have them installed on this server.

Digging into fcgiwrap(8), when started by systemd it expects to get a listening socket on standard input, on which it then calls accept(2). s6-ipcserver-socketbinder can provide such a socket, though it must be instructed to make the socket blocking, which is not the default. The finished artifact is a systemd user unit file which looks like this:

[Unit]
Description=fcgiwrap

[Service]
ExecStartPre=/bin/mkdir -m 755 -p /path/to/socketdir
ExecStart=/usr/bin/s6-ipcserver-socketbinder -a 0777 -B /path/to/socketdir/sock fcgiwrap -f

[Install]
WantedBy=default.target

nginx can then be configured to send FastCGI requests to this socket, e.g.:

location / {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /path/to/werc/bin/werc.rc;
    fastcig_pass unix:/path/to/socketdir/sock
}


home