Removes persistentTimer from all borgbackup services and unnecessary network-online.target dependencies. Changes fuchsia offsite to 14:00 fixed schedule when system is reliably awake. Persistent timer catch-ups immediately after system resume caused failures due to services starting before network/system fully stabilized: - Onsite: DNS resolution failures (viridian.home.arpa) - Offsite: BorgBase connection refusals during SSH/borg handshake Fixed schedules provide reliable backups without catch-up complexity: - fuchsia offsite: 14:00 daily (typical awake time for desktop) - viridian offsite: midnight daily (always-on server) - All onsite: hourly (no catch-up needed) Offsite services retain wants/after dependencies on onsite completion to prevent race conditions on shared /btrfs-subvolumes snapshot paths. Network dependencies removed as fixed schedules run when system is already stable, eliminating timing issues with network-online.target.
114 lines
3.2 KiB
Nix
114 lines
3.2 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
...
|
|
}: {
|
|
# Encrypted passphrase for offsite borgbackup repository
|
|
age.secrets.borgbackup = {
|
|
rekeyFile = ./passphrase.age;
|
|
};
|
|
|
|
# Create staging directory before borg service starts
|
|
systemd.tmpfiles.rules = [
|
|
"d /btrfs-subvolumes 0755 root root -"
|
|
];
|
|
|
|
# Wait for onsite backup to complete before starting offsite
|
|
systemd.services."borgbackup-job-offsite" = {
|
|
wants = ["borgbackup-job-onsite.service"];
|
|
after = ["borgbackup-job-onsite.service"];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
};
|
|
};
|
|
|
|
services.borgbackup.jobs."offsite" = {
|
|
# Allow writing to staging directory
|
|
readWritePaths = [ "/btrfs-subvolumes" ];
|
|
|
|
preHook = let
|
|
subvolumes = [
|
|
"srv-containers"
|
|
"srv-forgejo"
|
|
"srv-lighttpd"
|
|
"srv-minecraft"
|
|
"srv-opengist"
|
|
];
|
|
in /* sh */ ''
|
|
# Clean up orphaned snapshots from failed runs (crash/power loss)
|
|
for subvol in ${toString subvolumes}; do
|
|
[ -d "/btrfs-subvolumes/$subvol" ] && \
|
|
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
|
"/btrfs-subvolumes/$subvol" 2>/dev/null || true
|
|
done
|
|
|
|
# Create read-only BTRFS snapshots for backup
|
|
for subvol in ${toString subvolumes}; do
|
|
case "$subvol" in
|
|
srv-containers) src="/srv/multimedia/containers" ;;
|
|
srv-*) src="/srv/''${subvol#srv-}" ;;
|
|
esac
|
|
|
|
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
|
|
"$src" "/btrfs-subvolumes/$subvol"
|
|
done
|
|
'';
|
|
|
|
# Backup staging snapshots and explicit persistent files
|
|
paths = [
|
|
"/btrfs-subvolumes/srv-containers"
|
|
"/btrfs-subvolumes/srv-forgejo"
|
|
"/btrfs-subvolumes/srv-lighttpd"
|
|
"/btrfs-subvolumes/srv-minecraft"
|
|
"/btrfs-subvolumes/srv-opengist"
|
|
|
|
# Persistent files (actual storage location)
|
|
"/persist/etc/machine-id"
|
|
"/persist/etc/ssh/ssh_host_rsa_key"
|
|
"/persist/etc/ssh/ssh_host_rsa_key.pub"
|
|
"/persist/etc/ssh/ssh_host_ed25519_key"
|
|
"/persist/etc/ssh/ssh_host_ed25519_key.pub"
|
|
|
|
# Persistent directories (actual storage location)
|
|
"/persist/var/lib/bluetooth"
|
|
"/persist/var/lib/nixos"
|
|
"/persist/var/lib/private"
|
|
"/persist/etc/NetworkManager/system-connections"
|
|
];
|
|
|
|
postHook = let
|
|
subvolumes = [
|
|
"srv-containers"
|
|
"srv-forgejo"
|
|
"srv-lighttpd"
|
|
"srv-minecraft"
|
|
"srv-opengist"
|
|
];
|
|
in /* sh */ ''
|
|
# Clean up snapshots after successful backup
|
|
for subvol in ${toString subvolumes}; do
|
|
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
|
"/btrfs-subvolumes/$subvol"
|
|
done
|
|
'';
|
|
|
|
# Remote repository configuration
|
|
repo = "r7ag7x1w@r7ag7x1w.repo.borgbase.com:repo";
|
|
|
|
encryption = {
|
|
mode = "repokey-blake2";
|
|
passCommand = "cat ${config.age.secrets.borgbackup.path}";
|
|
};
|
|
|
|
environment.BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key";
|
|
compression = "zstd,9";
|
|
startAt = "daily"; # Daily at midnight
|
|
|
|
# Retention policy for daily remote backups
|
|
prune.keep = {
|
|
daily = 7; # Keep 7 daily backups (1 week)
|
|
weekly = 4; # Keep 4 weekly backups (1 month)
|
|
monthly = 12; # Keep 12 monthly backups (1 year)
|
|
};
|
|
};
|
|
}
|