mipo

Backups

The Backups page configures automated and on-demand backups of the database cluster. The two toggles, times, and retentions are labelled "Config DB" and "Results DB" — a legacy naming from before the schemas shared one TimescaleDB cluster. They are NOT independent today: a backup runs (producing a FULL cluster bundle) at BOTH scheduled times whenever EITHER toggle is enabled, and the effective retention is the LONGER of the two values. Backups are encrypted at rest ONLY when an encryption key is configured (the default is no key → bundles are stored UNENCRYPTED); they can optionally be replicated to S3-compatible storage.

Inputs

NameDescriptionAllowed valuesDefault
Config DB Enabled Enable toggle (legacy "Config DB" label). Automated backups run at BOTH scheduled times whenever EITHER this or "Results DB Enabled" is on — they are an OR gate, not separate on/off switches Boolean true
Config DB Schedule Hour of day (UTC) for the first daily full-cluster backup (both times always run when backups are enabled) 0-23 02:00
Results DB Enabled Enable toggle (legacy "Results DB" label). See "Config DB Enabled" — either toggle on enables backups at both times Boolean true
Results DB Schedule Hour of day (UTC) for the second daily full-cluster backup 0-23 03:00
Config DB Retention Retention input (legacy label). The retention APPLIED to bundles is the LONGER of this and "Results DB Retention" 1-365 days 30
Results DB Retention Retention input (legacy label). The retention APPLIED to bundles is the LONGER of this and "Config DB Retention" 1-365 days 7
Minimum Free Space Backups are skipped if free disk space falls below this threshold Bytes (positive integer) 500 MB
Encryption Key Passphrase used to derive an AES-256 key for backup bundle encryption. Use a high-entropy value (generate one with the Generate Key button). Store the key securely outside mipo — without it, encrypted backups cannot be restored. Any string or empty to disable Empty (disabled)
S3 Bucket S3-compatible bucket for off-site backup replication Valid bucket name Empty (disabled)

Fields & columns

NameDescription
BundleUnique identifier for the backup bundle
TimestampWhen the backup was created
Config DBBundle size attributed to the config schedule (legacy field; the bundle is one cluster dump)
Results DBBundle size attributed to the results schedule (legacy field; the bundle is one cluster dump)

How to

Trigger an immediate backup

  1. Click the "Backup Now" button in the Actions section
  2. Wait up to 60 seconds for the backup container to process the request
  3. Check the Trigger History section for the result status

Configure S3 replication

  1. Enable S3 and fill in the bucket, region, access key, and secret key
  2. Click "Test Connection" to verify S3 access
  3. Click "Save Configuration" to persist the settings

Restore from a backup

  1. There is no restore action on this page — Admin > Backups is trigger/config/history only.
  2. On a running deployment (including production), restore via the operator CLI: from the deployment dir run `scripts/ops/restore.sh <bundle>` (it connects as the cluster owner, stops the app containers, and rewrites the entire cluster — config, jobs, and results schemas).
  3. On a fresh host before an owner exists, the Day-0 Setup Wizard offers a restore path — but only where the manager has owner DB access (dev / a host with OWNER_DATABASE_URL); the standard prod manager does not, so prod uses the CLI.

Gotchas

  • The backup container polls every 60 seconds, so triggered backups are not instantaneous.
  • Backups are skipped automatically when free disk space is below the configured minimum.
  • S3 endpoint is only needed for non-AWS S3-compatible providers (e.g., MinIO, Backblaze B2).
  • Restore is available via the Day 0 Setup Wizard (GUI upload or S3 pull) or the CLI script (scripts/ops/restore.sh). Restore endpoints at /api/setup/restore/* are only accessible before an owner exists.
  • The two retention values are NOT applied separately — every bundle is a full cluster snapshot, so the retention actually enforced is the LONGER of the "Config DB" and "Results DB" values (default: 30 days, the max of 30 and 7). Set the value you actually want as the larger of the two.
  • There is no key escrow — losing the encryption key makes encrypted backups permanently unrecoverable. Store the key in a secure vault separate from the backup storage.
  • Take a fresh backup before an in-place upgrade. The `mipo.sh deploy` preflight reports the newest backup age as an informational line but does NOT block the upgrade on it (owner decision 2026-07-08: backup freshness is a deployer judgment call). The other preflight checks — schema drift, disk free, scanner protocol, downgrade — remain fail-closed. See Admin > Release for the upgrade-readiness view and `docs/operations/upgrade.md` for the runbook.

API calls (8)

MethodPathDescription
GET /api/admin/backups/config Retrieve current backup configuration
PUT /api/admin/backups/config Update backup configuration
GET /api/admin/backups List existing backup bundles
POST /api/admin/backups/trigger Trigger an immediate backup
GET /api/admin/backups/triggers List backup trigger history
POST /api/admin/backups/test-s3 Test S3 connection with current settings
GET /api/admin/backups/:id/download Download a backup bundle
POST /api/admin/backups/generate-encryption-key Generate a new backup encryption key (server-side crypto)

Related

  • Backup Health — Shows real-time backup process status and last run result
  • Settings — System-wide settings that affect backup behavior
  • Maintenance — Quick-access backup trigger and S3 test without leaving the maintenance page
  • Release — Release shows the last backup timestamp alongside the rest of the upgrade-readiness posture.