feat(backup): add restic backup role with encrypted incremental snapshots
Restic-backed backups using a many-to-many repository/job model. - repository = destination: restic repository URL verbatim (s3, local, removable device), backend credentials via env passthrough, retention policy, and an optional per-repository ntfy notify channel - job = source set: paths, sqlite and postgres dumps (consistent .backup / pg_dump instead of torn live-file copies), pushed to one or more repos - systemd timer per job, per-repo + per-job flock serialisation, restic check with read_data_subset for rotating integrity verification Service roles declare what to back up (ntfy_backup_*, uptime_kuma_backup_*); the inventory declares where.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=Backup job %i
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart={{ backup_script_path }} %i
|
||||
|
||||
# Creates /run/backup for the per-repository lock files, and removes it on
|
||||
# stop. /run is a tmpfs, so the directory cannot simply be created once.
|
||||
RuntimeDirectory=backup
|
||||
RuntimeDirectoryMode=0700
|
||||
|
||||
# Backups are I/O heavy and never urgent: stay out of the way of live services.
|
||||
Nice=10
|
||||
IOSchedulingClass=idle
|
||||
|
||||
# A hung run holds the repository lock and blocks every other job against the
|
||||
# same destination, so it must be killed rather than left to hang forever.
|
||||
TimeoutStartSec={{ backup_timeout }}
|
||||
Reference in New Issue
Block a user