Linux – How to manage a systemd service which needs multiple processes

crashlinuxprocesssystemd

I have a website which requires several processes to be running (python, node, etc). I currently have a systemd service created so I can easily start and stop those processes. I created a start script which launches all of the processes I need as background processes (appending & to the end of the command).

This prevents me from being able to make use of systemd's auto restart feature when something crashes since all of the processes are starting under a single script.

One potential solution I can think of would be to create a service for each process, and then link them all together by creating a master service which Requires them. I'm not a fan of this because it means I need to create 4-5 services for every environment of this website I want to run.

Is there a way I can easily define a service that starts multiple processes and monitors each of them individually?

Best Answer

Create several template services, which are named with an @ like this:

  • website@.service
  • pythonthingy@.service
  • nodethingy@.service

Using templates, you can start a named instance for each website:

systemctl start pythonthingy@clientone.service nodethingy@clientone.service
systemctl start pythonthingy@clienttwo.service nodethingy@clienttwo.service

Within such template units, you can use %i to reference the instance name ("clientone" in this example). So the "main" unit (service or target) could have:

[Unit]
Requires=pythonthingy@%i.service
...
[Service]
Environment="DOCROOT=/var/www/%i"

If each site needs multiple parameters, you can load them from a file:

[Service]
EnvironmentFile=/etc/someconfigdir/%i.conf

If some sites need nonstandard unit settings compared to the rest, use drop-ins:

  • pythonthingy@.service – the common template
  • pythonthingy@clientone.service.d/overrides.conf – extra parameters just for client 1

Templates, drop-ins, and expansions like %i are explained in systemd.unit(5).

Related Question