0014. Backups run restic through the node agent
Status: accepted, 2026-10-09
Context
backups needs deduplicated, compressed, encrypted snapshots on S3-compatible storage and SFTP, checks
that read the data back, and restores of a database, a folder or one file. Writing a repository format
of our own is a lot of code where a bug loses data. The candidates were kopia's Go library and restic.
Reading every database and data folder of the platform needs root, which backupsd shouldn't have
(ADR 0010: the node agent does privileged work).
Decision
- restic is the engine. Its repository format is documented and stable, it speaks S3 and SFTP,
restic check --read-data-subset verifies, and a snapshot can be restored with the stock restic
binary on any machine, without xvii: the recovery kit is the repository URL, its credentials and the
password.
- xvii-node runs it. backupsd (in the
xvii-admin group) asks the node agent over its socket to
back up sources (a database through pg_dump --format=custom piped into restic backup --stdin, a
folder directly) or restore them; the agent streams restic's JSON progress back. The agent installs
restic with the platform's packages.
- backupsd keeps the rest: destinations, plans, schedules, retention (
restic forget --keep-*),
the history of runs, verification, the panel, events to notify, limits.
- One repository per destination, tagged per source (
db:xvii_pages, path:pages), so retention and
restores work per source.
Consequences
- A second binary on every node; its version is pinned by xvii-node.
- Backups of apps on other nodes (stage 5) go through those nodes' agents the same way.
- kopia stays an option if restic's single-writer lock gets in the way of many parallel plans.