Backups and moving to a new Mac
Database backups happen every night on their own (Postgres, SQLite). For everything else there's one archive:
berth backup # → ~/berth-backup-<time>.tar.gz
berth backup /Volumes/USB/berth.tar.gz
It holds everything needed to rebuild: app settings and config, release history, fresh database backups and your storage folders. It leaves out anything that can be fetched or rebuilt again (git mirrors, images, logs). It has your secrets in it, so keep it somewhere safe.
To restore it, on the same Mac or a new one:
berth init --domain example.com # on a Mac with no apps yet
berth restore berth-backup.tar.gz
Everything comes back: each app's settings, config, domains, access rules,
workers and AI access; sign-in groups and sessions; Postgres, Redis and
SQLite from their backups; storage folders; and the GitHub, Cloudflare and Google logins.
Every app is redeployed from its repo at the commit that was live. A few
things come back lazily: apps without a repo come back with their settings
(push to them to deploy), dev versions on their next dev:push, previews
with their pull requests, and local AI models with berth ai:setup. LAN
addresses change to the new Mac's name.
Off-Mac backups
That archive lives on the Mac, which doesn't help much if the Mac dies or walks off. So send one somewhere else every night:
berth offsite:setup --r2 <cloudflare account id> --bucket my-berth-backups
After the 03:00 dumps, Berth makes the same archive as berth backup,
encrypts it on the Mac, uploads it, checks it arrived intact, and keeps the
newest 14 (--keep changes that). Any S3-compatible storage works. For
Cloudflare R2, create a bucket and an R2 API token with Object Read & Write
on it. For anything else (Backblaze B2, AWS S3, MinIO), pass --endpoint.
Setup asks for the secret key without echoing it, and tries writing, reading,
listing and deleting a test file before it saves anything.
Setup then prints a recovery code (berthrestore_…). It's the bucket's
address and credentials plus the key that encrypts the backups, all in one
string. Save it somewhere that isn't the Mac. A password manager is
perfect. The storage provider only ever sees ciphertext, and without the code
nobody can read the backups, including you. berth offsite:key prints it
again; it changes if you rerun setup with new credentials.
berth offsite:status # where they go, the last upload, what's in the bucket
berth offsite:run # upload one now
berth offsite:get # download and decrypt the latest, ready for berth restore
berth offsite:off # stop (the bucket keeps its backups)
berth status warns if no upload has worked for two days, and a failed
upload sends a notification.
Moving to a new Mac
With off-Mac backups, moving is one command on the new Mac, once Homebrew and Berth are installed:
berth init --restore # asks for the recovery code
It fetches the newest backup and puts the old Mac's settings and logins in
place. That means no --domain, and no Cloudflare or GitHub logins in the
browser, since it reuses the same tunnel and token. Then it finishes setting
up and restores every database and app as above.
Turn Berth off on the old Mac first (berth uninstall). Otherwise both Macs
share the tunnel and split your traffic between them, which is confusing.
Uninstalling
berth uninstall # stop everything and remove the background services; keeps ~/.berth
berth uninstall --purge # also delete every app, webhook, database volume, image and ~/.berth