-
Notifications
You must be signed in to change notification settings - Fork 0
Backup and Restore
Two things matter, and they must be stored separately.
Everything lives on the writ-data volume: the SQLite database (/data/writ.db)
and stored files (/data/files).
docker run --rm \
-v writ-oss_writ-data:/data \
-v "$PWD":/backup \
alpine tar czf /backup/writ-data-$(date +%F).tar.gz -C /data .Check the volume's real name with docker volume ls — it is prefixed by your
compose project.
For a consistent database snapshot, stop the coordinator first
(docker compose stop coordinator) or use SQLite's own backup API. Copying a
live SQLite file mid-write can capture a torn state.
This is not in the volume, and a backup without it is only partly restorable.
It encrypts personas, credentials, TOTP seeds and session cookies. Store it in a password manager or secrets store — somewhere that will survive losing the machine, and somewhere other than alongside the backup archive.
Losing it makes every stored credential unrecoverable. Replacing it does the same thing, and does it silently: the coordinator boots fine, and the failures only appear later when a workflow tries to decrypt a persona. If you ever regenerate
.env, carry the oldSECRET_ENCRYPTION_KEYacross.
Back up the rest of .env too — regenerating those secrets invalidates every
session and every issued fleet token, which means re-enrolling agents.
docker compose down
docker volume create writ-oss_writ-data
docker run --rm -v writ-oss_writ-data:/data -v "$PWD":/backup \
alpine tar xzf /backup/writ-data-YYYY-MM-DD.tar.gz -C /data
# put the ORIGINAL .env back, including SECRET_ENCRYPTION_KEY
docker compose up -dVerify: sign in, open a persona, and confirm a stored credential still decrypts. That is the check that actually proves the key matched.
Agents keep their own encrypted local database in WRIT_HOME (default
~/.writ). It holds local run state, not your workflows or credentials. It does
not need backing up — a replacement agent re-enrols and carries on.
There is no email reset; self-host has no required mail server. Whoever has server access resets it directly:
docker compose exec coordinator python reset_password.py
docker compose exec coordinator python reset_password.py --password 'YourNewPass1'For a run-local.sh install: bash reset-admin-password.sh, with --list to
show accounts. The reset also re-activates a disabled account.
To start completely over, stop the app and delete the database file — the next visit shows first-run setup again.
usewrit/writ · AGPL-3.0-only · Issues · Discussions · Report a vulnerability
Getting started
Using it
Integrations
Operations
Reference