Backup and restore
What holds state
Section titled “What holds state”| Where | What | Losing it means |
|---|---|---|
quasar-postgres-data volume |
Users, apps, hosts, sessions, entitlements, settings. Everything. | Total loss. Start over. |
| The managed home root | Every user’s save games and installed content. | Users lose their saves. |
deploy/.env |
QUASAR_SECRET_KEY, database password, enrollment token. |
Credentials stored through the admin UI become permanently unreadable. |
quasar-control-tls volume |
The TLS certificate and the artwork cache. | A new certificate is generated. Clients re-trust. Artwork re-fetches. |
quasar-agent-data volume |
The agent’s per-node enrollment secret. | The agent re-enrolls with the token. |
The first three matter. The last two regenerate.
Backing up the database
Section titled “Backing up the database”docker compose -f deploy/docker-compose.yml exec -T quasar-postgres \ pg_dump -U quasar -Fc quasar > quasar-$(date +%Y%m%d-%H%M).dumpCustom format, because it restores selectively and compresses.
Do this before every upgrade, on a schedule, and before anything you are unsure about.
Backing up saves
Section titled “Backing up saves”The managed home root is a directory on the host. Back it up like any other directory.
tar -czf quasar-homes-$(date +%Y%m%d).tar.gz -C /var/lib/quasar homesIt will be large. Users install games into it.
If hosts use different local roots, back up every one. A shared root only needs one storage-level backup, but test it from each GPU host so a mount failure does not look like an empty library after recovery.
Backing up the environment file
Section titled “Backing up the environment file”cp deploy/.env quasar-env-$(date +%Y%m%d).backupIt contains secrets. Store it accordingly.
Restoring
Section titled “Restoring”-
Stop the control plane. Never restore over a live database.
Terminal window docker compose -f deploy/docker-compose.yml stop quasar-control-plane -
Restore into a fresh database. Restoring over an existing one is how you end up with a half-merged state that looks fine and is not.
Terminal window docker compose -f deploy/docker-compose.yml exec -T quasar-postgres \pg_restore -U quasar -d quasar --clean --if-exists --no-owner --no-privileges \--exit-on-error < quasar-20260810-1430.dump -
Restore
deploy/.env, in particularQUASAR_SECRET_KEY. A restored database with a different secret key has credentials it cannot decrypt. -
Restore the home directories if you are restoring those too.
-
Start the control plane and let it apply any migrations.
Terminal window docker compose -f deploy/docker-compose.yml start quasar-control-plane -
Verify. Health endpoint, hosts registered, a real session.
Developer restore rehearsal
Section titled “Developer restore rehearsal”Contributors can exercise the database mechanism in a disposable environment.
This is a development check, not an operator restore command; it never touches
the deployed .env, database, or volumes.
bash deploy/db-backup-restore-drill.shIt builds the control plane from source, migrates a blank database, seeds real rows across the tables that matter (including entitlements, because a partial restore that dropped those would silently empty every user’s library), dumps, restores into a separate database, then checks that the schema hashes match, that the seeded rows survived, and that the same binary starts cleanly against the restored database.
See Testing and verification for the rest of the developer verification workflow.
Version compatibility
Section titled “Version compatibility”There is no published matrix of which control plane versions work with which database states. Combined with the one-way migration rule, the practical policy is: back up before every upgrade, and restore rather than rolling back.
See Upgrading.