Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Backup Options

This module is provided by nixfleet-scopes. It is documented here as part of the NixFleet ecosystem reference.

All options under nixfleet.backup. The module is auto-included by mkHost and disabled by default. Enable with nixfleet.backup.enable = true.

The backup scope is backend-agnostic. It creates the systemd timer and service skeleton. Set backend to "restic" or "borgbackup" to use a built-in backend, or set systemd.services.nixfleet-backup.serviceConfig.ExecStart directly to use any other tool.

Options

OptionTypeDefaultDescription
enableboolfalseEnable NixFleet backup scaffolding (timer, health, persistence).
backendnullOr enum ["restic" "borgbackup"]nullBackup backend. Null = fleet sets ExecStart manually.
pathslistOf str["/persist"]Directories to back up.
excludelistOf str["/persist/nix" "*.cache"]Patterns to exclude from backup.
schedulestr"daily"Systemd calendar expression (e.g., daily, weekly, *-*-* 02:00:00).
retention.dailyint7Number of daily snapshots to keep.
retention.weeklyint4Number of weekly snapshots to keep.
retention.monthlyint6Number of monthly snapshots to keep.
healthCheck.onSuccessnullOr strnullURL to GET on successful backup (e.g., Healthchecks.io ping URL).
healthCheck.onFailurenullOr strnullURL to GET on backup failure.
preHooklines""Shell commands to run before backup.
postHooklines""Shell commands to run after successful backup.
stateDirectorystr"/var/lib/nixfleet-backup"Directory for backup state/cache. Persisted on impermanent hosts.

restic backend options

Active when backend = "restic". The restic package is added to environment.systemPackages automatically.

OptionTypeDefaultDescription
restic.repositorystr""Restic repository URL or path. Example: "/mnt/backup/restic".
restic.passwordFilestr""Path to file containing the repository password. Example: "/run/secrets/restic-password".

borgbackup backend options

Active when backend = "borgbackup". The borgbackup package is added to environment.systemPackages automatically.

OptionTypeDefaultDescription
borgbackup.repositorystr""Borg repository path or ssh://user@host/path.
borgbackup.passphraseFilenullOr strnullPath to file containing the repository passphrase. Null = repokey without passphrase.
borgbackup.encryptionstr"repokey"Borg encryption mode (repokey, repokey-blake2, none, etc.).

Systemd timer

SettingValue
Unitnixfleet-backup.timer
WantedBytimers.target
OnCalendarvalue of schedule
Persistenttrue (catch up on missed runs)
RandomizedDelaySec1h (stagger across fleet)

Systemd service

SettingValue
Unitnixfleet-backup.service
Typeoneshot
Afternetwork-online.target
Wantsnetwork-online.target
StateDirectorynixfleet-backup
ExecStart(set by fleet module)

After a successful backup run, the service writes status.json to stateDirectory:

{"lastRun": "2025-01-15T02:00:00+00:00", "status": "success", "hostname": "web-01"}

When healthCheck.onFailure is set, a companion nixfleet-backup-failure.service is registered as the OnFailure handler.

Impermanence

On impermanent hosts (nixfleet.impermanence.enable = true), the scope automatically persists stateDirectory.

Example - restic (built-in backend)

nixfleet.backup = {
  enable = true;
  backend = "restic";
  paths = ["/persist/home" "/persist/var/lib"];
  schedule = "*-*-* 03:00:00";
  retention = { daily = 7; weekly = 4; monthly = 3; };
  healthCheck.onSuccess = "https://hc-ping.com/your-uuid-here";
  restic = {
    repository = "s3:s3.amazonaws.com/my-bucket/backups";
    passwordFile = "/run/secrets/restic-password";
  };
};

Example - borgbackup (built-in backend)

nixfleet.backup = {
  enable = true;
  backend = "borgbackup";
  paths = ["/persist/home" "/persist/var/lib"];
  schedule = "weekly";
  retention = { daily = 7; weekly = 4; monthly = 6; };
  borgbackup = {
    repository = "ssh://backup-user@backup-host/var/backups/myhost";
    passphraseFile = "/run/secrets/borg-passphrase";
    encryption = "repokey-blake2";
  };
};

Example - custom backend (manual ExecStart)

{config, pkgs, ...}: {
  nixfleet.backup = {
    enable = true;
    paths = ["/persist/home" "/persist/var/lib"];
    schedule = "*-*-* 03:00:00";
    retention = { daily = 7; weekly = 4; monthly = 3; };
    healthCheck.onSuccess = "https://hc-ping.com/your-uuid-here";
  };

  systemd.services.nixfleet-backup.serviceConfig.ExecStart = let
    resticCmd = "${pkgs.restic}/bin/restic";
    repo = "s3:s3.amazonaws.com/my-bucket/backups";
  in ''
    ${resticCmd} -r ${repo} backup \
      ${builtins.concatStringsSep " " config.nixfleet.backup.paths} \
      ${builtins.concatStringsSep " " (map (p: "--exclude=${p}") config.nixfleet.backup.exclude)} \
      --forget \
      --keep-daily ${toString config.nixfleet.backup.retention.daily} \
      --keep-weekly ${toString config.nixfleet.backup.retention.weekly} \
      --keep-monthly ${toString config.nixfleet.backup.retention.monthly}
  '';
}