# 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 ```bash node scripts/restoreFullBackup.js path/to/fondwaypoints-full-backup-.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`](../../.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.