minimal systemd "unit" file

 I used to use daemontools for running servers under process supervision.  There are other similar systems like runit.

Now, most current linux distributions use systemd.  This is presented as a disaster by purists, but the fact is, everyone else failed to make anything adequate while systemd crept up.  Unix has a process tree, so use it.  Instead of which, every shonky init script had its own error-prone concoction of pid files, daemon that backgrounds itself, commands like "stop" or "reload" that LOOK AT THE PID FILE and send it a signal.  As a side-whinge, most daemons automatically go thru a cargo-cult absurdity of detach and fork and background, or whatever the fuck it is.  A lot of the time, you can ask them not to do this, often with arcane options (look at apache: -DFOREGROUND -DNO_DETACH).  It should not even be possible, let alone some default the long-suffering sysadmin has to work around, differently for each application.  The people complaining about systemd did nothing to make simple process-supervision normal, instead of init script swamp.

systemd thingies are called units, and they are defined in unit files, in the somewhat completion-unfriendly /etc/systemd/system/*.service.

I want to keep stuff agnostic to the process supervision system, so I want as little config as possible in the unit file.  Not even the user to run it as -- that can be defined via dropto in the run script.

So what is the minimal unit file for a service?  From my non-exhaustive tinkering, the minimum appears to be three sections, each with one parameter.  Let's start with a complete example using the minimal scheme, then describe each element.

Contents of  /etc/systemd/system/wiki.ptj.apache2.service:


[Unit]

Description=wiki.ptj


[Service]

ExecStart=/etc/wiki.ptj.apache2.run


[Install]

WantedBy=multi-user.target


For Unit->Description, I found I couldn't add / enable the service without this.  I don't see the problem with using the filename stem as the default description, so I don't agree with the design of requiring this item, but that's a relatively minor design quibble.

Service->ExecStart is a clumsy way of saying the actual thing to run.  Note it's a single executable name with no options.  This means the same script can be used from daemontools and the like, as the run script.  In daemontools it has to be called "run", so it would be a symlink from a file called "run" in the service dir, or a copy under that name.  It doesn't have a basename of "run" in my systemd scheme because systemd's logging prefixes the basename of this executable to log lines.  The quickest way I found to stop all server log lines being tagged "run", was to put the server name in the run program name as above.

Again, the privilege-dropping is done inside the run-program, so after systemd, but before the server application, so no relying on shonky-unique-cargo-cult privilege-dropping from the application.  Basically "exec dropto USER ..." is how the shell script that runs the server goes.

Finally, Install->WantedBy with value "multi-user.target" is an extremely clumsy way of saying to run this server at runlevel 3 or multi-user mode.

Enabling and starting it interactively, with a quick check, then, is something along the lines of:

export SV=wiki.ptj.apache2; systemctl enable $SV && systemctl start $SV && sleep 2 && systemctl status $SV


Comments

Popular posts from this blog

the persistent idiocy of "privileged ports" on Unix

google is giving more and more 500 errors

7 minute workout: a straightforward audio recording (and two broken google web sites)