backup-strategy.md now leads with the three target legs (local incus push to sdb, nuc pull over WireGuard, restic to S3 for DBs and selected trees) and carries the plakar/ks2 story in a closing History section. restic-backup.md, install.md, local-backup-cron.md and the ks2 docs describe the predecessor only as 'the first S3 implementation', with one operational note that plakar is still installed for issue #2338 reproduction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.0 KiB
2.0 KiB
local backup cron on ks4 (leg 1)
Enabled 2026-08-22 (both ks4 backup crons had been commented out — no backup of any kind was running). Overview of all legs: ../backup-strategy.md.
What runs now (root crontab on ks4)
0 1 * * * /root/scripts/incus-copy.sh -p backup -s backup >> /var/log/incus-copy.log 2>&1
01:00— local leg:incus copy --refreshof all instances into projectbackupon the sdb5backupzpool (replaces the old push to ks2; see incus-copy.md). An S3 leg for the instance filesystems was designed and shelved (restic-backup.md §6).- The rsync stopgap to ks2 (
incus-backup.sh, 04:00) and the first S3 implementation (04:30) are both retired; S3 backups are restic's job at 05:00 (restic-backup.md).
Cleanup done the same day
- ks2:
incus delete biwiki spot(abandoned instances — freed space on the 95 %-fulldatapool) - ks4:
incus delete spot --project backup
Verification
# all instances present, incl. livetrail (first copy is a full send)
sudo incus list --project backup -c ns -f csv
# cron runs land here (manual screen runs don't):
sudo tail /var/log/incus-copy.log /var/log/incus-backup.log
# rsync leg freshness, on ks2:
ls -lat /backup/ns3061243/ | head
Notes:
flockin both scripts makes overlapping cron/manual runs abort safely instead of racing.- Replicas get
boot.autostart=falseset by the script — they must never fight the live instances for their static IPs. - Keep
snapshots.scheduleset on the sources so refreshes stay ZFS-incremental (a refresh without common snapshots falls back to rsync). Corollary: the cron must run at least everysnapshots.expiry(7 d) — a longer gap expires every common snapshot and the next refresh silently degrades to a full re-send (observed 2026-08-22: seafile re-sent 933 G after the weeks-long gap while the crons were commented out).