Backups
Everything an inbox holds is in one SQLite file: requests, threads, settings, keys, receipts, and the secrets it keeps sealed. Two things restore it whole:
- A backup of the database. A copy made by the inbox itself, never a copy of the file while it runs, which can be caught halfway through a write.
INBOX_SECRET_KEY. The sealed secrets (calendar and payment connections, webhook secrets, the key that signs receipts) open only with it. Without it a backup restores every request and setting, and those connections have to be made again. Keep it apart from the backups, in a password manager.
A backup on the same disk as the inbox protects from mistakes, not from losing the server: copy backups somewhere else too.
On your own server
Section titled “On your own server”The installer makes a backup every night at about 03:30, server time, and keeps the last seven. Any time:
sudo inbox backupEach is one file in /opt/inbox/data/backups, named by its time (inbox-20261020T033012Z.db), readable by its owner only. The inbox writes it while it keeps serving (VACUUM INTO), checks it, and only then gives it its name. sudo inbox update makes one before every update, and sudo inbox restore one before every restore.
To copy them off the server, any tool that copies files will do. For example, every night after the backup, with rclone set up for your storage:
# /etc/cron.d/inbox-offsite (or a systemd timer): the backups to your own storage, at 04:3030 4 * * * root rclone copy /opt/inbox/data/backups yourstorage:inbox-backups --max-age 48hRestoring
Section titled “Restoring”sudo inbox restore /opt/inbox/data/backups/inbox-20261020T033012Z.dbIt looks at the file first (that it is an inbox’s database, sound, and from this version or an older one), says what it holds, and asks. Then it makes a backup of the inbox as it is now, copies the backup into place, stops the inbox only for the swap, and starts it. If the inbox does not start on it, it puts back what was there. The last five backups made before a restore are kept. A backup from an older version is brought up to date when the inbox starts; one from a newer version is refused until you update.
On a new server: run the installer with the same address, then put your INBOX_SECRET_KEY in /opt/inbox/.env in place of the one it generated (sudo nano /opt/inbox/.env), sudo inbox restart, and restore.
With Docker or Compose of your own
Section titled “With Docker or Compose of your own”docker exec inbox node /opt/inbox/server.mjs backup /opt/inbox/data/backups/inbox-$(date -u +%Y%m%dT%H%M%SZ).dbdocker exec inbox node /opt/inbox/server.mjs check-db /opt/inbox/data/backups/<file> # before a restoreThe backup command makes the backups folder when it is not there yet.
To restore by hand: stop the container, replace inbox.db in the data folder with the backup (and delete inbox.db-wal and inbox.db-shm beside it), give it to uid 10001, and start the container.
Litestream
Section titled “Litestream”Litestream copies the database to S3-compatible storage within seconds of every change, so a lost server loses at most those seconds. It runs beside the inbox, as a second line next to the nightly backups. On a server the installer set up:
cd /opt/inboxsudo curl -fsSLO https://raw.githubusercontent.com/surfingdogai/inbox/main/deploy/litestream/docker-compose.litestream.ymlsudo curl -fsSLO https://raw.githubusercontent.com/surfingdogai/inbox/main/deploy/litestream/litestream.ymlsudo curl -fsSL https://raw.githubusercontent.com/surfingdogai/inbox/main/deploy/litestream/litestream.env.example -o litestream.envsudo chmod 600 litestream.env && sudo nano litestream.env # the bucket, its endpoint, and a key for that bucket onlysudo inbox startIts keys stay in litestream.env, apart from the inbox’s own settings. With the file there, the inbox command runs Litestream beside the inbox from then on, and stops it while a restore, a rollback or an update swaps the database. To restore from it, into a file the inbox then restores from:
sudo docker compose -f docker-compose.yml -f docker-compose.litestream.yml run --rm litestream \ restore -o /opt/inbox/data/from-litestream.db /opt/inbox/data/inbox.dbsudo inbox restore /opt/inbox/data/from-litestream.dbOn a platform
Section titled “On a platform”Fly.io and Render snapshot their volumes and disks daily, and DigitalOcean can back up a whole Droplet; the platforms page says how each keeps its data. The inbox’s own backup command works on each of them, and Litestream does too.
On Cloudflare
Section titled “On Cloudflare”On Workers the database is D1, and D1 keeps its own history: Time Travel restores it to any minute of the last 30 days (7 on the free plan).
npx wrangler d1 time-travel info surfingdog-inboxnpx wrangler d1 time-travel restore surfingdog-inbox --timestamp=2026-10-20T03:30:00Znpx wrangler d1 export surfingdog-inbox --remote --output=inbox.sql # a copy to keep elsewhereTaking your data with you
Section titled “Taking your data with you”Apart from backups, the owner app downloads everything the inbox holds, without sign-ins or secrets, ready to bring into another inbox.