# Importing this adds a daily borg backup job to a node. # It has all the common config and keys, and can be configured # to back up more (or entirely different) folders. { lib, config, pkgs, ...}: let cfg = config.services.private-storage.borgbackup; inherit (config.grid) publicKeyPath privateKeyPath; # Get a per-host number so backup jobs don't all run at the # same time. ip-util = import ../../nixos/lib/ip-util.nix; backupDelay = with builtins; bitAnd (ip-util.fromHexString (hashString "md5" config.networking.hostName)) 15; in { options.services.private-storage.borgbackup = { enable = lib.mkEnableOption "Borgbackup daily backup job"; paths = lib.mkOption { type = lib.types.listOf lib.types.str; description = '' A list of directories to back up using Borg. ''; default = [ "/storage" ]; }; }; config = lib.mkIf cfg.enable { deployment = { secrets = { "borgbackup-passphrase" = { # The passphrase is used to encrypt the repo key # https://borgbackup.readthedocs.io/en/stable/usage/init.html destination = "/run/keys/borgbackup/passphrase"; source = "${privateKeyPath}/borgbackup.passphrase"; }; "borgbackup-appendonly-ssh-key" = { # The ssh key is used to authenticate to the remote repo server destination = "/run/keys/borgbackup/ssh-key"; source = "${privateKeyPath}/borgbackup.ssh-key"; }; }; }; services.borgbackup.jobs = { daily = { paths = cfg.paths; repo = lib.fileContents "${publicKeyPath}/borgbackup/${config.networking.hostName}.repopath"; doInit = false; encryption = { mode = "repokey-blake2"; passCommand = "cat /run/keys/borgbackup/passphrase"; }; environment = { BORG_RSH = "ssh -i /run/keys/borgbackup/ssh-key -o StrictHostKeyChecking=accept-new"; }; # Output statistics after uploading a backup set extraCreateArgs = "--stats --json"; # All logs in JSON to help Prometheus/Grafana extraArgs = "--log-json"; # Ciphertext doesn't compress well compression = "none"; # Start the backup at a different time per machine, # and not at the full hour, but somewhat later startAt = "*-*-* " + toString backupDelay + ":22:11 UTC"; }; }; # Check repo once a month systemd.services.borgbackup-check-repo = { # Once a month, 3h after last backup started startAt = "*-*-" + toString backupDelay + " 18:33:22 UTC"; path = [ pkgs.borgbackup ]; environment = { BORG_PASSCOMMAND = "cat /run/keys/borgbackup/passphrase"; BORG_RSH = "ssh -i /run/keys/borgbackup/ssh-key -o StrictHostKeyChecking=accept-new"; BORG_REPO = lib.fileContents "${publicKeyPath}/borgbackup/${config.networking.hostName}.repopath"; }; script = ''${pkgs.borgbackup}/bin/borg check''; }; }; }