services: use wants dependency where possible

Let A be a service that depends on another service B.
When A can gracefully handle failures and restarts of B, use
```
wants = [ "B.service" ];
after = [ "B.service" ];
```
instead of
```
requires = [ "B.service" ];
after = [ "B.service" ];
```
in the definition of A.

This way, A keeps running when B is stopped or restarted after a failure.
With `requires`, A is instead stopped when B is stopped or restarted due to a failure.

This brings two benefits:

1. Improved uptime
Examples:
- RTL keeps running when one lightning node has failed
- btcpayserver keeps running and accepting on-chain payments when the lightning node has crashed

2. Avoids a systemd bug where depending units (`A.service` in the
above example) are not restarted when their dependency fails
(issue github/systemd#18856, no full link to avoid spamming the issue).
In real world nix-bitcoin deployments, this issue was only likely to
appear when clightning failed during activation, causing depending
units (like `RTL`) to stop and not be restarted.
All services depending on `clightning` have now been changed to use
`wants`, thereby avoiding the bug.

Services `electrs` and `lightning-loop` fail when their respective
dependencies stop, so these services have not been changed.
I also haven't changed services `joinmarket` and
`joinmarket-yieldgenerator`. Further manual testing is needed to
determine if they can be switched to `wants`.
This commit is contained in:
Erik Arvstedt 2025-01-20 22:47:40 +01:00
parent c7e5de3b2b
commit 4aaef5fdf4
No known key found for this signature in database
GPG key ID: 33312B944DD97846
7 changed files with 19 additions and 17 deletions

View file

@ -171,8 +171,9 @@ in {
'';
in rec {
wantedBy = [ "multi-user.target" ];
requires = [ "bitcoind.service" "postgresql.service" ] ++ optional cfg.btcpayserver.lbtc "liquidd.service";
after = requires ++ [ "nix-bitcoin-secrets.target" ];
requires = [ "postgresql.service" ];
wants = [ "bitcoind.service" ] ++ optional cfg.btcpayserver.lbtc "liquidd.service";
after = requires ++ wants ++ [ "nix-bitcoin-secrets.target" ];
preStart = ''
install -m 600 ${configFile} '${cfg.nbxplorer.dataDir}/settings.config'
{
@ -223,11 +224,12 @@ in {
lbtcexplorerurl=${nbExplorerUrl}
lbtcexplorercookiefile=${nbExplorerCookie}
'');
in let self = {
in rec {
wantedBy = [ "multi-user.target" ];
requires = [ "nbxplorer.service" "postgresql.service" ]
++ optional (cfg.btcpayserver.lightningBackend != null) "${cfg.btcpayserver.lightningBackend}.service";
after = self.requires;
requires = [ "postgresql.service" ];
wants = [ "nbxplorer.service" ]
++ optional (cfg.btcpayserver.lightningBackend != null) "${cfg.btcpayserver.lightningBackend}.service";
after = requires ++ wants;
serviceConfig = nbLib.defaultHardening // {
ExecStart = ''
${cfg.btcpayserver.package}/bin/btcpayserver --conf=${configFile} \
@ -244,7 +246,7 @@ in {
} // nbLib.allowedIPAddresses cfg.btcpayserver.tor.enforce;
startLimitIntervalSec = 30;
startLimitBurst = 10;
}; in self;
};
users.users.${cfg.nbxplorer.user} = {
isSystemUser = true;