Turn it on
Connect two backup destinations first (see Backups and storage). Then choose the second one:- Dashboard: Settings, Backup targets, Second destination.
- CLI:
levelrail-cli backups destinations copy set <destination>. Useoffto stop,showto read the setting. - API:
PUT /api/v1/backups/copy-settingswith{"enabled": true, "target_id": "..."}.
See the state
levelrail-cli backups copies list (or GET /api/v1/backups/copies, or the table on the same settings page) shows each backup with its copy status and lag. Lag is the time from the backup finishing to the copy landing, or to now while it is still waiting. A failed copy is retried on the next pass with its last error shown.
Get alerted
Create a rule of kindbackup_copy_behind; it also ships as a default rule. It fires while any backup has had no copy for longer than the limit:
--for-duration, for example 2h.
Settings
Control plane environment variables:
Restore always reads from the primary destination; the second copy is for recovery when the primary is gone.
Verification and manifest
Each copy is read back and its SHA-256 compared with the primary’s recorded checksum. A<object>.manifest.json sidecar (checksum, codec, tree digest, size) is written next to the copied object, so a restore from the second destination alone has what it needs. A copy only counts as succeeded after both are in place.
Local directory targets
For small boxes and tests, setAPP_BACKUP_LOCAL_ROOT to an absolute directory, then add a target with levelrail-cli backups targets add --type local --name NAME --path SUBDIR. The path is relative to the root and cannot leave it (symlinks included). No keys are needed. The root is returned read-only as local_root by backups targets list and show, and the dashboard form shows it as the folder prefix.