15

I've written a program that uses a Postgres database, and I wrote a systemd service file for it. Currently my service gets started on boot just fine, and it gets stopped when Postgres is stopped for upgrading (by apt upgrade). However, when the upgrade is complete and Postgres is started again, my service is not automatically started.

Can I define some dependency to get my service started again automatically?

This is the status of my service after it was automatically stopped during the Postgres upgrade:

● tabill.service - My service
   Loaded: loaded (/srv/tabill/tabill.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Tue 2017-07-04 00:29:24 EEST; 44min ago
 Main PID: 1048 (code=killed, signal=TERM)

Note that I can manually start the service again just fine.

Here's my service file:

[Unit]
Description=My service
Wants=nginx.service
Requires=postgresql.service
After=postgresql.service

[Service]
Type=simple
ExecStart=/srv/tabill/app/serve
Restart=always
TimeoutSec=60

[Install]
WantedBy=multi-user.target

I've tried adding PartOf=postgresql.service and BindsTo=postgresql.service, and then manually stopping and starting Postgres, but neither helped.

Of course I could remove the Requires, but stopping both services together is preferable, if only they would both start back up.

3
  • PartOf= sounds like the right solution. Did you try it with Requires= removed? – meuh Jul 4 '17 at 9:45
  • @meuh I tried it now with Requires= removed, that didn't help. I think the problem is that PartOf= links "stopping and restarting of units", but Postgres isn't restarted during an upgrade. It's stopped, upgraded, and started. – Rennex Jul 4 '17 at 20:32
  • 1
    Amusingly enough, when you do systemctl restart postgresql, systemd remembers to restart its dependent services again. It seems like apt, for some reason, does combination of stop and start instead of restart. – WGH Mar 10 '18 at 23:34
16

I found the answer: I needed to change the last line of the service file to:

WantedBy=postgresql.service

This way, whenever Postgres is started, my service is started too - but if my service fails, that doesn't stop Postgres.

Directives in the [Install] section only affect enabling and disabling of units. But it wasn't this simple when my service was already enabled:

# systemctl enable tabill.service
Failed to execute operation: Too many levels of symbolic links

The error message was misleading. Fixing it was simple:

# systemctl disable tabill.service
Removed symlink /etc/systemd/system/tabill.service.
Removed symlink /etc/systemd/system/multi-user.target.wants/tabill.service.

# systemctl enable tabill.service
Failed to execute operation: No such file or directory

# systemctl enable /srv/tabill/tabill.service
Created symlink from /etc/systemd/system/postgresql.service.wants/tabill.service to /srv/tabill/tabill.service.
Created symlink from /etc/systemd/system/tabill.service to /srv/tabill/tabill.service.

Now my service stops and starts whenever Postgres does. And naturally Postgres starts when the system boots.

1
  • This doesn't sound like a proper solution because your database does not really depend on your unit. Essentially you formed a two-way dependency while it is really a one-way. I think there is either a bug in systemd here or we are missing something. – silverwind yesterday

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.