Backup and Restore

AuraBoot persists state in three independent stores. A complete backup must cover all three, and a restore drill must be exercised on a non-production environment before you trust it.

StoreWhat it holds
PostgreSQLTenant data, dynamic tables (mt_<modelCode>), audit logs, BPM state
Plugin DSLModel / page / command / permission JSON (the configuration source of truth)
MinIO (S3-compatible)Uploaded files, exported reports, attachments

A backup that covers only PostgreSQL will lose plugin upgrades and uploaded files. A backup that covers only DSL will lose every tenant record.

When to use

  • Before a production upgrade (see Upgrade).
  • Before re-running reset-and-init.sh on a shared environment.
  • On a recurring schedule for disaster recovery.
  • Before destructive operations such as schema migrations or large data imports.

How it works

PostgreSQL is dumped with pg_dump against the primary node. The dump is logical (SQL or custom format) so it can be restored across minor versions. The source of truth for Plugin DSL is the plugin directory on disk (model / page / command / permission JSON), so archiving the plugin source directory captures a versioned snapshot. MinIO is mirrored using mc mirror against the configured bucket.

The three artifacts share a common backup id so that point-in-time restore is possible: PostgreSQL dump, DSL archive, and object mirror taken within the same window can be replayed together.

Configuration and commands

# 1. PostgreSQL dump (custom format, parallel jobs)
PGPASSWORD="$PG_PASSWORD" pg_dump \
  -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" \
  -d aura_boot \
  -Fc -j 4 \
  -f "/backups/auraboot-$(date +%Y%m%d-%H%M%S).dump"

# 2. Plugin DSL archive (tar the plugin source directory on disk)
tar -czf "/backups/auraboot-dsl-$(date +%Y%m%d-%H%M%S).tar.gz" \
  -C "$AURA_PLUGINS_DIR" .

# 3. MinIO bucket mirror
mc mirror --overwrite --remove \
  auraboot-prod/aura-files \
  /backups/minio/$(date +%Y%m%d-%H%M%S)/

For restore on a clean target:

# 1. Recreate database (matches reset-and-init.sh contract)
yes y | ./scripts/reset-db.sh

# 2. Restore PostgreSQL dump
PGPASSWORD="$PG_PASSWORD" pg_restore \
  -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" \
  -d aura_boot -j 4 --clean --if-exists \
  /backups/auraboot-20260528-020000.dump

# 3. Replay DSL (extract the plugin source dir, then directory-sync import)
tar -xzf /backups/auraboot-dsl-20260528-020000.tar.gz -C /restore/plugins
curl -sS -X POST -H "Authorization: Bearer $AURA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"path":"/restore/plugins","conflictStrategy":"OVERWRITE"}' \
  "$AURA_API_URL/api/plugins/import/import-directory-sync"

# 4. Restore MinIO objects
mc mirror /backups/minio/20260528-020000/ auraboot-prod/aura-files

Retention policy

A reasonable default:

TierFrequencyRetain
HourlyEvery hour24 hours
Daily02:00 local14 days
WeeklySunday 02:008 weeks
MonthlyFirst of month12 months

Adjust per regulatory and storage budgets. Keep at least one off-site copy.

Verify

  • The dump file is non-empty and pg_restore --list prints expected schemas.
  • A staging environment restored from last night's backup boots, /actuator/health returns UP, and an end-to-end login plus list-page render succeeds.
  • DSL replay finishes with zero references unregistered handler errors (see Plugin Development).
  • File count and total bytes of restored MinIO bucket match source within tolerance.
  • Restore drill cadence is at least quarterly; an untested backup is not a backup.

Related