The trick here is to use a dummy program to start the wrapper and hold them active after the program was terminated.
dummy-master.service
[Unit]
Description=Dummy Master Service
[Service]
# The dummy program will exit
Type=oneshot
# Execute a dummy program
ExecStart=/bin/true
# This service shall be considered active after start
RemainAfterExit=yes
[Install]
# Components of this application should be started at boot time
WantedBy=multi-user.target
dummy-db.service
[Unit]
Description=Dummy Database
# When systemd stops or restarts the dummy-master.service, the action is propagated to this unit
PartOf=dummy-master.service
# Start this unit after the dummy-master.service start
After=dummy-master.service
[Service]
User=dummyuser
Type=forking
# Pretend that the component is running
ExecStart=/usr/local/database.sh start
ExecStop=/usr/local/database.sh stop
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
Restart=on-failure
[Install]
# This unit should start when app.service is starting
WantedBy=dummy-master.service
dummy-listener.service
[Unit]
Description=Dummy Listener
# When systemd stops or restarts the dummy-master.service, the action is propagated to this unit
PartOf=dummy-master.service
# Start this unit after the dummy-master.service start
After=dummy-master.service
After=dummy-db.service
[Service]
User=dummyuser
Type=forking
# Pretend that the component is running
ExecStart=/usr/local/listener.sh start
ExecStop=/usr/local/listener.sh stop
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
Restart=on-failure
[Install]
# This unit should start when dummy-master.service is starting
WantedBy=dummy-master.service
dummy-cron.service
[Unit]
Description=Dummy Cron
# When systemd stops or restarts the dummy-master.service, the action is propagated to this unit
PartOf=dummy-master.service
# Start this unit after the dummy-master.service start
After=dummy-master.service
After=dummy-listener.service
[Service]
User=dummyuser
Type=forking
# Pretend that the component is running
ExecStart=/usr/local/cron.sh start
ExecStop=/usr/local/cron.sh stop
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
Restart=on-failure
RemainAfterExit=yes
[Install]
# This unit should start when dummy-master.service is starting
WantedBy=dummy-master.service
After defining the related services, you have to enable all of them.
systemctl enable dummy-master dummy-db dummy-listener dummy-cron
Now you can control the whole workflow with one systemd script:
systemctl start|stop|status dummy-master