I plan to host several instances of the same web app for customers using systemd
. I would like to be able to stop
and start
each customer instance using systemd
, as well as treating the whole collection of customer instances as a single service that can be stopped and started together.
systemd
seems to provide the building blocks I need using PartOf
, and template unit files, but went I stop the parent service, the child customer service is not stopped. How can I make this work with systemd? Here's what I have so far.
The parent unit file, app.service
:
[Unit]
Description=App Web Service
[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal
A unit template file named app@.service
, used to create customer instances:
[Unit]
Description=%I Instance of App Web Service
[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal
My app-poc.sh
script (Proof of concept that just prints to log file in a loop):
#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
echo "The App PoC loop for $@"
sleep 2;
done
For the proof of concept, I've got the systemd unit files in ~/.config/systemd/user
.
I then start up the parent and an instance based on the template (after systemctl --user daemon-reload
):
systemctl --user start app
systemctl --user start app@customer.service
From using journalctl -f
I can see that both started and that the customer instance continues to run. Now I I expect shutting down the parent will stop the child (because I used PartOf
), but it doesn't. Also, starting the parent isn't starting the child as expected either.
systemctl --user stop app
Thanks!
(I'm using Ubuntu 16.04 with systemd 229).
Best Answer
You need to move the line
out of
[Service]
and into the[Unit]
section, and add to the[Unit]
ofapp.service
the list of customers to start, egor as sourcejedi said in the comments,
Requires=
the same thing. You can keep thePartOf
to stop services you start by hand that are not in the above list, likesystemctl --user start app@customer3.service
.