Capital's PostgreSQL database holds the trade history, accounting, strategy allocations and configuration. It must survive a disk failure.
| Item | How | Why |
|---|---|---|
| Database | make backup → data/backups/*.sql.gz |
Trades, positions, equity history, settings |
.env |
Copy somewhere secure, separately | Holds CAPITAL_SECRET_KEY |
⚠ The database dump does not contain
.env. The Binance/LLM API keys in the database are encrypted withCAPITAL_SECRET_KEY. A database restored without the exact secret key cannot decrypt them. Back up.envseparately and securely.
make backup # or: scripts/backup.shThis runs pg_dump --clean inside the postgres container and writes a
timestamped, gzipped SQL file to data/backups/ — which lives off the
database's data volume. The newest 14 dumps are kept (CAPITAL_BACKUP_RETAIN
overrides the count).
Run it from cron on the host — e.g. a daily 03:00 backup:
0 3 * * * cd /opt/capital && /usr/bin/make backup >> data/backups/backup.log 2>&1make restore # restores the most recent dump
scripts/restore.sh data/backups/capital-20260521T030000Z.sql.gzThe restore is destructive — it overwrites the current database — and asks
for a typed confirmation first. Because dumps are taken with --clean, a
restore drops and recreates objects in place.
Verify backups are usable — do not assume:
- Take a backup:
make backup. - Bring up a throwaway database and restore into it:
docker compose down -v # wipes the data volume docker compose up -d postgres scripts/restore.sh # restores the latest dump
- Start the stack and confirm the dashboard shows the expected trade history, positions and equity curve.
- Confirm stored API keys still work — this proves the
.env/CAPITAL_SECRET_KEYyou restored alongside the database matches.