Data and backups

There are two backup scopes, and they are independent:

ScopeHoldsWho backs it up
The InstallerIts own database, its secrets, and the deployment files it generatedYou
DataMind OSThe business data of every deployed serviceYou — the Installer does not back up the stack it deploys

What does the DataMind Installer itself store?

Five things, and only one of them is truly irreplaceable.

StoreContentsRecreatable?
configurations tableEvery generated and operator-supplied deployment value — the whole deployment environmentOnly from a backup
users, refresh_tokensAdministrator accounts and live sessionsYes, by registering again
system_secretsThe Azure client secret and the VM user, encryptedYes, if you still have the values
deployment_actions, deployment_job_eventsThe audit trail and the log history of every jobNo — history cannot be recreated
Secrets volumejwt.secret, encr.key, curato.token, pg.passSigning and service tokens regenerate; the encryption key does not

The configuration rows are the important part. They are what renders deployment/.env, and a lost configuration set means reconstructing the entire environment by hand.

Important

Back up the database and the secrets volume together. A database dump without encr.key restores rows whose secret values can never be decrypted again.

Where is the Installer's database, and how do I back it up?

In the pgdata Docker volume; dump it with pg_dump from inside the container.

bash
docker exec delamain-postgres pg_dump -U postgres -d delamain > delamain-$(date +%F).sql

pg_dump produces a consistent snapshot even while the Installer is running, so you do not need a maintenance window for this. Restoring is the reverse:

bash
cat delamain-2026-09-29.sql | docker exec -i delamain-postgres psql -U postgres -d delamain
Note

On a development install the container is delamain-postgres-dev and the database name is still whatever POSTGRES_DATABASE_NAME says — delamain by default in both files.

What volumes does the Installer create?

Two, by default.

VolumeMounted atContents
pgdata/var/lib/postgresql/dataThe Installer's database
delamain_secrets/usr/src/app/secrets in the backend, /run/secrets in PostgresThe four generated secret files

The development compose file uses the _dev variants, pgdata_dev and delamain_secrets_dev, so a development install and a production install on the same host do not share state.

bash
docker volume ls | grep delamain

Which files on the host are irreplaceable?

Three classes of file, in descending order of how much trouble losing them causes.

FileWhy it matters
encr.key in the secrets volumeEncrypts every stored secret and generated value. Losing it means re-entering them all
pg.pass in the secrets volumeThe password of the running database role; needed to reach existing data
the Installer's own .envHolds POSTGRES_USER, POSTGRES_DATABASE_NAME and DOCKER_SOCK, which must keep matching the existing installation
deployment/.envRegenerable from configuration rows — but only if the database survives
deployment/docker-compose.override.ymlYours, and never written by the Installer. Nothing recreates it
deployment/docker-compose.ymlRe-downloadable from blob storage
deployment/.env.unified.templateRe-downloadable from blob storage

How do I back up the secrets volume?

Archive the volume's contents with a throwaway container.

bash
docker run --rm \
  -v delamain_secrets:/secrets:ro \
  -v "$PWD":/backup \
  alpine tar czf /backup/delamain-secrets-$(date +%F).tgz -C /secrets .

Restoring is the same operation in reverse. Keep the archive somewhere with the same protection as the secrets themselves — it is, effectively, the key to the deployment's credentials.

What happens if I lose the delamain_secrets volume?

The Installer comes back up, but stored secrets do not. On the next start it generates whatever is missing: a new JWT signing secret, a new encryption key, a new service token. The consequences follow from that:

Lost fileConsequence
encr.keyEvery stored secret and generated value fails to decrypt. The Azure secret reports a decryption error and must be re-entered
jwt.secretEveryone is signed out
curato.tokenThe service channel breaks until the deployment .env is regenerated with the new value
pg.passWorse than the others. PostgreSQL generates a password only when the file is empty, and the existing database role keeps its original password — so the Installer cannot connect until you reconcile the two
Warning

Losing encr.key is not a self-healing failure. Restore it from your backup, or re-enter every secret and generated value by hand. See Configuration and variables.

How do I back up a DataMind OS deployment?

Per service, using each service's own mechanism — plus a copy of the resolved configuration and the compose file. The Installer has no backup feature and does not run backups for the stack.

A workable minimum:

  1. Back up each stateful service's data volumes with the service stopped or quiesced, or with the service's own dump tool.
  2. Copy deployment/.env, deployment/docker-compose.yml and deployment/docker-compose.override.yml.
  3. Export the Installer's configuration rows (GET /api/configs) so you can reconstruct the environment if the Installer's database is lost.
  4. Export the deployment action audit trail.
Tip

Stop the stack before copying raw data-directory volumes. A file-level copy of a running database's data directory is not a backup — it is a plausible-looking file that will not restore.

Where does the DataMind OS .env live, and should I back it up?

At deployment/.env on the host — and yes, take a copy, but know what it is. It is a generated artifact: every save, seed and restore rewrites it in full from the Installer's configuration rows. It also contains live service credentials, so treat the copy as a secret.

It is worth having because it is the fastest way to see what the deployment was actually running at a point in time, and because it lets you start the stack if the Installer is unavailable.

Can I restore a backup onto a different host?

Yes, with two caveats. Your host-specific and encrypted values come with the dump, and you must also move the secrets volume.

  1. Install the Installer on the new host with the same .env values for POSTGRES_USER, POSTGRES_DATABASE_NAME and DOCKER_SOCK.
  2. Stop it, restore the secrets volume, then restore the database dump.
  3. Start it and check the deployment status.

The caveats: host-computed values are recalculated, not restored. Memory limits are derived from the new machine's total memory, so a restored configuration set will be re-sized for the new host. And the deployment files are re-downloaded rather than restored, so a hand-edited override file must be copied across deliberately.

Moving to a new host walks through the same procedure as a planned migration, including the checks to run before you switch production over.

How do I take a backup without stopping anything?

Dump the database live; quiesce only the services whose data you are copying. The split is:

WhatSafe live?
Installer database (pg_dump)Yes — the dump is consistent
Installer secrets volume (files)Yes — the files are written once and then only read
Configuration export (GET /api/configs)Yes
DataMind OS service data volumesNo — stop or quiesce the service first
The deployment docker-compose.yml and .envYes
Note

The database dump and the secrets archive should be taken close together. A dump restored beside an older encryption key produces exactly the decryption failure described above.

Does an update back anything up?

The Installer's self-update backs up its own compose file, and nothing else. Before the switch, the helper copies the live compose file to docker-compose.yml.pre-update next to it, and restores that file if the update fails. That backup protects the update itself; it is not a data backup.

A DataMind OS update takes no backup at all. Take one before you update production.

Warning

docker-compose.yml.pre-update is overwritten by the next self-update. Do not treat it as a version history.

Can I recreate the downloaded deployment files?

Yes, from blob storage, with an administrator call. Both files are published artifacts, so they can be fetched again at any time:

bash
curl -X POST http://localhost:8000/api/registry/download-compose-file \
  -H "Authorization: Bearer <access-token>"

curl -X POST http://localhost:8000/api/registry/download-env-template \
  -H "Authorization: Bearer <access-token>"

The Installer also restores them by itself at boot if they are missing and the Azure client secret is configured. Downloading the environment template re-seeds the configuration rows as a side effect, so read that question in Configuration and variables before you run it.

Important

These downloads use the Azure client secret. Without it they fail, and the failure is reported as a missing deployment file rather than as an authentication problem — check the secret first.

How do I export the deployment audit trail?

Page through the actions endpoint and save the JSON, or query the table directly.

bash
curl -s "http://localhost:8000/api/deployment/actions?limit=100&offset=0" \
  -H "Authorization: Bearer <access-token>" \
  -o actions-$(date +%F).json
sql
-- from psql inside delamain-postgres
\copy (SELECT action, services, job_id, status, exit_code, user_id, detail, created_at
       FROM deployment_actions ORDER BY created_at) TO 'actions.csv' WITH CSV HEADER

The table is never pruned, so a periodic export gives you an audit history that outlives the host.

How do I reset the Installer to a clean state?

Stop the containers, remove the volumes, and start again — this destroys everything the Installer holds. It is the right action when you want to rebuild a deployment from scratch and you have decided the configuration set is not worth keeping.

Run these from the Installer's install directory:

bash
docker compose down
docker volume rm delamain_secrets pgdata
rm -rf deployment/
docker compose up -d
Warning

This is irreversible. The database holds the entire deployment configuration and the audit trail; the secrets volume holds the encryption key. If either matters, back it up first. Removing the deployment files does not touch the DataMind OS stack's own data or its Docker volumes — those are separate and must be removed deliberately if that is what you want.

For step-by-step backup and restore procedures, see Backup and restore.