Backup and restore
What to back up, what the platform backs up for you, and the exact commands to restore each of them.
What you must back up yourself
/etc/sthora/master.key
Every environment variable, deploy key, webhook secret, and managed-service credential is encrypted under it. Losing it does not lose the platform — it loses every secret the platform is holding, unrecoverably. Copy it off the box.
Also worth copying off the box:
| Why | |
|---|---|
/etc/sthora/.env | The generated database and Redis passwords and AUTH_SECRET. Reconstructing them is not possible; without AUTH_SECRET every session and API token digest is meaningless. |
The acme.json volume of sthora-proxy | Certificates. Losing it means re-issuing everything, against Let's Encrypt's five-failures-per-hostname-per-hour limit. |
| Application volumes | Nothing backs these up for you. |
What the platform backs up
| Where | Retention | |
|---|---|---|
| The platform database, nightly | /var/lib/sthora/backups/platform/ | PLATFORM_BACKUP_RETENTION_COUNT (7) |
| The platform database, before every upgrade | The same directory, named pre-upgrade-<timestamp>.dump | Not pruned |
| Managed services | /var/lib/sthora/backups/<slug>/, or the configured S3 bucket | Per service, 1–365 |
PLATFORM_DATABASE_CONTAINER unset means the database is not one this
platform runs — an external or managed instance, whose backups are its owner's
job. The nightly dump is skipped.
Restoring
The platform database
docker compose -p sthora stop api worker
docker cp <dump> sthora-postgres:/tmp/restore.dump
docker exec sthora-postgres \
pg_restore --username sthora --dbname sthora --clean --if-exists /tmp/restore.dump
docker compose -p sthora start api workerStop the API and worker first. Restoring under a running control plane races every write it is making.
A managed PostgreSQL
docker cp <backup>.dump sthora-svc-<slug>:/tmp/restore.dump
docker exec sthora-svc-<slug> \
pg_restore --username sthora --dbname app --clean --if-exists /tmp/restore.dumpA managed Redis
docker cp <backup>.rdb sthora-svc-<slug>:/data/dump.rdb
docker restart sthora-svc-<slug>The restart is not optional — Redis loads its dump only at startup.
A managed MinIO
docker cp <backup>.tar.gz sthora-svc-<slug>:/tmp/restore.tar.gz
docker exec sthora-svc-<slug> tar -xzf /tmp/restore.tar.gz -C /dataMoving to a new machine
The whole platform is /etc/sthora plus /var/lib/sthora plus the database. Install
on the new box, restore both directories and the database dump, and re-run the installer to
bring the stack up against them.
Applications have to be redeployed — their images and containers live on the old machine's Docker daemon and do not travel.