How to shutdown a service before backup (restic)?

Hello,

I’m trying to deploy a backup system using restic on my server. Everytime the backup is running, I would like to shutdown the targeted service before backing it up. For instance I want to backup vaultwarden and before running the backup process I would like the vaultwarden systemd unit to be shutdown and started back when it’s done.

I’m wondering how to proceed with that, namely:

  1. Should I rely on backupPrepareCommand/backupCleanupCommand from the NixOs Options or
  2. Should I rely on another Systemd mechanism I’m not aware of ?

As a side question, if 1. is the solution, is there a way I can target the Systemd service like with some kind of ${pkgs.vaultwarden.service} black Nix magic (and how could I have found this information myself) ?

Thanks in advance !

If you want to go full systemd, you can create a target which is required by the restic, and which conflicts with some target for services that shouldn’t run. wire up your dependencies with bindsTo and life should be groovy. man system.unit and read the whole thing. Reading reference docs e2e is the only way to get a view of the landscpe. The man paages for unit/service/exec/target (and related referenced man pages) are basically required reading if you want to use systemd with ease.

Hello @bme,

thanks for your suggestion, I did not think of using the conflict mechanism this way. But this will only solve part of the issue as it won’t restart the backed up service once backup is done or am I missing something ?

In any case I’ll be going through those man pages, you’re right that I don’t have a view of the landscape when it comes to systemd.

There sadly isn’t a good way to do it. There is a hacky way though. Please read

I use this to export my paperless:

The best is to not have to shut down the services at all and do an atomic backup on another layer such as the filesystem. If you use a snapshotting filesystem, you can simply create a snapshot and then back up the snapshot. Because a snapshot guarantees an atomic state and is read-only, any well made application can recover from it, even if it’s not in an entirely clean state from its perspective (it’s as if you suddenly lost power).

2 Likes

I guess first off I would second what @Atemu is saying re: gaining atomicity via snapshotting is the better way. That said what I was thinking was two targets backup.target and not-backup.target, where all the services you want stopped bind to not-backup.target, and the two tagets conflict. Then I would make restic have a pre/post run script which starts backup.target and not-backup.target resp.

I think that should work, I’ve done something similar in the past at a previous gig, but I don’t have the code to hand. Caveat emptor.

1 Like

Thanks for your suggestions, that’s actually really interesting!

One question though, I tried using directly the backupPrepareCommand/backupCleanupCommand of the Restic service and doing some systemctl stop vaultwarden inside and it seems to work correctly.

I guess it’s not a good solution as you both pointed out the systemd ones, is there a reason for that ?

The vaultwarden module already provides an option for a backup directory where it dumps its own backup. Not at my computer, but I believe it creates a separate copy of the database.

Edit: the module creates a backup service too.

That’s perfectly correct in the case of vaultwarden. It is more of a general question as it isn’t the only service I’m running. Also I like as much as possible to have the same backup mechanisms for all my services that’s why in the case of vaultwarden I probably won’t rely on the provided one anyway.

Basis for my suggestion is that is externalises dependency management in a way that is introspectable, because systemd has introspection tools. I think that’s nice. Strictly speaking if you make two nice scripts then you have the same power of abstraction, but you can’t introspect what the “state” of your dependency management is. Having a target would give you that at a glance.

1 Like

Right, got it. Thanks for all those inputs. I think I’m going to revisit this whole thing to see if I can implement those suggestions, that seems nice indeed.

Certain databases (Postgres as an example) do not completely support live file system backup or add a lot of asterisks to it as they cannot guarantee consistency of the data on disk at an arbitrary point in time.

1 Like

The primary benefit is that systemd’s Conflicts= directive completely prevents the coflicting service from starting while the backup service is running.

I hadn’t thought of that, makes perfectly sense.