Backups & restore¶
Everything Ribbon knows (family, people, gifts, occasions, wishlists, logins) lives in one SQLite file, ribbon.db, in the ribbon_data Docker volume. That makes backups simple: keep a copy of that file somewhere other than the server.
A backup on the same disk is not a backup
Ribbon's scheduled snapshots are stored inside the same volume as the database. They protect you from mistakes (a bad import, an accidental delete), not from a dead disk or a lost server. Copy them elsewhere too.
Scheduled backups¶
Ribbon snapshots the database on a schedule into <DATA_DIR>/backups (/data/backups in Docker).
| Setting | Default | Meaning |
|---|---|---|
BACKUP_CRON |
0 3 * * * |
When to snapshot: five-field cron (minute hour day month weekday). off disables. |
BACKUP_KEEP |
14 |
How many scheduled snapshots to keep. |
The schedule uses the container's clock (UTC unless you set TZ). Snapshots are consistent copies taken while Ribbon is running (VACUUM INTO), written with owner-only permissions.
Files are named auto-YYYYMMDD-HHMMSS.db (scheduled), manual-... (taken from Settings) and pre-restore-... (the safety copy taken just before a restore; the newest 5 are kept).
In the app: Settings → Data¶
Only the instance owner (the first owner) sees the backup tools. They let you:
- Back up now, taking a snapshot immediately.
- Download any snapshot to your computer.
- Restore from a file by choosing a snapshot from the list, or by uploading a
.dbfile.
A restore takes a safety copy first. Logins that are not in the restored file stop working, and a file with no owner login is refused (it would lock everyone out). Files from a newer version of Ribbon, and files that are not Ribbon databases, are refused.
Other ways to export¶
- Export ledger (JSON): Settings → Data → Export ledger saves gifts, people and occasions (not logins). Import ledger restores it. The same JSON is at
/api/exportwhen you are signed in. - CSV: gifts, people or wishlists as spreadsheets. See CSV import and export. CSV is for moving data around, not a full backup.
Copy the database file by hand¶
Copy ribbon.db (logins and sessions included). For a perfectly clean copy, stop the app first:
docker compose stop ribbon
docker run --rm -v ribbon_ribbon_data:/data -v "$PWD":/backup busybox \
cp /data/ribbon.db /backup/ribbon-backup.db
docker compose start ribbon
The volume is named <folder>_ribbon_data (here the folder is ribbon); check with docker volume ls. To copy the whole backups folder too, replace the cp with cp -a /data/. /backup/ribbon-data/.
Back up the volume with your usual tool
If you already back up your Docker volumes with restic, borg, Duplicati or a snapshotting filesystem, point it at the ribbon_data volume. SQLite is safe to copy while idle; the nightly backups/ snapshots are always safe to copy.
Restore¶
- Sign in as the instance owner.
- Settings → Data, then pick a snapshot (or upload a
.dbfile) and choose Restore. - Sign in again if asked. Ribbon takes a
pre-restoresafety copy first.
docker compose stop ribbon
docker run --rm -v ribbon_ribbon_data:/data -v "$PWD":/backup busybox \
cp /backup/ribbon-backup.db /data/ribbon.db
docker compose start ribbon
Put the file back at /data/ribbon.db while the app is stopped. If the container runs as the node user and the new file is not readable, fix ownership with chown 1000:1000 /data/ribbon.db in the same helper container.
Install Ribbon as in Getting started, stop it after the first start, copy your ribbon.db over /data/ribbon.db as above and start it again. Your owner login and family are already there, so there is no first-run setup.
Test your backup¶
A backup you have never restored is a hope, not a backup. Once, on a spare machine, install Ribbon, restore a snapshot and sign in. It takes five minutes.