Skip to content

Backup and Restore

j5guy edited this page Jul 25, 2026 · 2 revisions

Backup and Restore

A backup is a download of your vault exactly as the server stores it — every item's name, data, and file attachments stay ciphertext the whole time, plus the wrapped vault key needed to unwrap them. Nothing is decrypted to build the file, and nothing in it is usable without your master password: restoring re-derives your key from a password typed into the browser and either the unwrap succeeds or it doesn't, the same way logging in does. Treat a downloaded backup file like the master password itself — anyone with both can read your vault.

  • Download a backup — Settings → Backup. Re-enter your master password first (this doesn't change what a live session could already read via the API, it's just friction against an idle unlocked tab producing a portable file). Downloads a single JSON file containing your account's key material, every waypoint, category/tag names, item-to-item links, and every file attachment (base64-encoded, still ciphertext).
  • Restore into the same account — Settings → Backup → "Restore into this account". Only works against a backup made from this account (checked via a vault-key fingerprint before anything is written) — useful for undoing an accidental bulk delete. Existing categories/tags are matched by name and reused; missing ones are created.
  • Restore onto a rebuilt server/auth/restore (linked from the login page). For when the account doesn't exist at all anymore (e.g. the database was lost). Creates a brand new account from the backup's key material, logs in, then replays every waypoint/link/upload back in through the normal per-item API. A Recovery Kit isn't carried over by this path — generate a new one from Settings afterward if you want one.

Scheduled, whole-server backups (Admin)

The per-account export above is a personal safety net — anyone can trigger it from their own Settings page, no server access needed. Admin > Scheduled Backups is a separate, deployment-level feature for disaster recovery of the entire server: every account's key material, waypoints, links, uploads, categories/tags, and the admin Settings singleton (e.g. SMTP config), dumped straight from MongoDB on a schedule you control. Same zero-decryption property as the per-account export — the server already stores this as ciphertext, so producing the file never needs anyone's master password.

  • Enable it, set a frequency (in hours) and a retention count (how many backup files to keep — older ones are deleted automatically) from Admin > Scheduled Backups. Saving there overrides .env (BACKUP_ENABLED/BACKUP_FREQUENCY_HOURS/BACKUP_RETENTION_COUNT) and takes effect within 15 minutes, no redeploy needed. Run backup now triggers one immediately, useful for checking your configuration works before trusting the schedule.
  • Backup files land in BACKUP_DIR (default backups/ inside the app; already mounted to a backups-data Docker volume in docker-compose.yml so they survive the container being recreated). Download any of them from the same admin page.

Restoring onto a new deployment

node scripts/restoreFullBackup.js path/to/fondwaypoints-full-backup-<timestamp>.zip

Run this against a fresh install (empty database) — it refuses to run against a database that already has accounts in it, unless you pass --force (which wipes every collection it restores before writing, for re-testing a restore rather than everyday use). It connects using this deployment's own .env (mongoHost/mongoUser/mongoPass/etc. — see .env.example), the exact same connection logic (config/mongoUri.js) the app itself uses to talk to MongoDB.

This means restoring works identically no matter what MongoDB the new deployment uses — the bundled Docker container, or an external server, and it doesn't need to match whatever the old deployment used. Restore has no special-cases for "internal" vs. "external" Mongo: it just writes documents into whichever one .env currently names. Point mongoHost (and mongoUser/mongoPass if it needs auth) at wherever MongoDB lives now, run the script once, and every account is back exactly as it was — including uploaded file attachments, copied out of the zip into public/uploads/ — with everyone's original master password still working, since restoreFullBackup.js restores the authentication hash along with everything else. No signup, no CLI account creation step, no per-account replay required.

Clone this wiki locally