Skip to main content
A self-hosted deployment keeps all of its state in Docker volumes plus a handful of configuration files. Backing up means archiving both; there is no separate export step inside the application.
A volume backup is only usable together with the deployment’s secrets. CYMPH_ENCRYPTION_KEY and CYMPH_ENCRYPTION_IV in .env, and the key in db/secrets.txt, are generated once at setup and cannot be regenerated. Without them, sensitive integration data in a restored database cannot be decrypted. Always back up the configuration files alongside the volumes.

What to back up

cymph_log-data (nginx logs) is worth keeping if you retain logs for compliance reasons. cymph_embedding-data holds only a cached model and is re-downloaded automatically — skip it.

Choosing a method

Volume snapshots are the recommended approach. One mechanism captures the database and the application data together at the same point in time, and restore is a straight extraction — no schema migration, no dump-format compatibility to think about between versions. The trade-off is that copying a live PostgreSQL data directory is not crash-consistent, so the stack has to be stopped while the archive is taken. In practice this fits the maintenance window you already take for upgrades.
If you need backups without downtime, use pg_dump against the db container for the database and snapshot cymph_api-data separately. That gives you a hot backup but two restore paths to manage instead of one.

Taking a backup

  1. Stop the stack from the directory containing compose.yaml:
  1. Archive each volume through a throwaway container:
  1. Copy the configuration files:
  1. Start the stack again:
  1. Move the backup directory off the host, to wherever you keep encrypted backups. It contains the deployment’s secrets in plaintext, so treat it accordingly.
Volume names are prefixed with the Compose project name, which is cymph. If you renamed the project, confirm the real names with docker volume ls.

Restoring

Restore onto a host with the same Cymph release the backup was taken from. Restoring into a newer release is not supported — restore first, then upgrade.
  1. Extract the release bundle and put the saved configuration files back in place. Do not run env.sh — it would generate new secrets and make the backup undecryptable.
  1. Make sure nothing is running, and remove the volumes that the restore will replace:
  1. Recreate the volumes and extract the archives, preserving ownership so PostgreSQL can read its data directory:
  1. Confirm the TLS certificate and key are present at the paths recorded in .env — those are host paths and are not part of the volume backup. See TLS certificates.
  2. Start the stack:
  1. Verify the restore. docker compose ps should show every service healthy, and you should be able to log in with the credentials that were in use when the backup was taken — user accounts and passwords come from the restored database, not from setup.
If the db service fails its healthcheck after a restore, check its logs first — a permissions problem on the data directory is the usual cause, and it means step 3 ran without -p or without root: