Backup and restore
A Function Client server keeps its state in four places. Back up all four together:
| What | Where | Why it matters |
|---|---|---|
.env.selfhost | the repository's top directory | holds ENCRYPTION_MASTER_KEY. Without that exact key, every connected integration's stored credentials are unreadable after a restore, and every person has to connect them again. |
| MongoDB | the mongo-data volume, database mirra | accounts, spaces, messages, flows, everything but the graph |
| Neo4j | the neo4j-data volume | the memory graph |
| Object storage | the s3-data volume | uploaded files, images, recordings |
Redis holds only caches and can be left out. The edge-data volume holds
the edge's certificates, which it obtains again by itself.
.env.selfhost alone lets its holder sign in as anyone on the live server
(JWT_SECRET), and with the data it unlocks every stored integration
credential. Keep the backup readable only by you, and encrypt it before it
leaves the machine.
The commands below run from the repository's top directory and write to
backup/. Compose names the volumes mirra_<name> (the compose file's
project name; with docker compose -p <project> they are <project>_<name>,
so change the docker run lines to match). Each backup overwrites the last,
so copy backup/ somewhere else, off the machine.
Back up
To copy it off the machine, encrypt it first, for example
tar -C backup -cz . | gpg --symmetric --cipher-algo AES256 -o ~/client-backup-$(date +%F).tgz.gpg,
and keep the passphrase somewhere other than the backup.
While Neo4j and object storage are stopped, the app keeps running, but memory and uploads fail for those minutes.
The database's name is DB_NAME, which compose sets to mirra. It never
comes from the connection string's path. Outside compose, the MongoDB step
is mongodump --uri "$DB_CONNECTION_STRING" --db "$DB_NAME" --archive --gzip.
Restore
On a new machine, or after down -v: check out the same release you backed
up, and put the backup in backup/.
Try a restore on a spare machine before you need one.