Skip to content

Backup and Restore

Writ edited this page Jul 28, 2026 · 2 revisions

Backup and restore

Two things matter, and they must be stored separately.

1. The data volume

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.

2. SECRET_ENCRYPTION_KEY

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 old SECRET_ENCRYPTION_KEY across.

Back up the rest of .env too — regenerating those secrets invalidates every session and every issued fleet token, which means re-enrolling agents.

Restore

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 -d

Verify: sign in, open a persona, and confirm a stored credential still decrypts. That is the check that actually proves the key matched.

What is not backed up

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.

Forgotten admin password

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.

Clone this wiki locally