Backup and Restore
Run a full backup immediately before every helm upgrade. Database schema migrations may run automatically during an upgrade — if the upgrade fails mid-migration, the pre-upgrade backup is your only guaranteed rollback path for the data layer.
Plexicus stores persistent state in three places:
| Component | Data stored | Default service name |
|---|---|---|
| MongoDB | Findings, users, repositories, scan results, enrichment data | mongodb |
| PostgreSQL (Temporal) | Workflow history and Temporal visibility records | temporal-postgresql |
| Object storage (MinIO or external S3) | Scan artifacts, AI inputs/outputs, scan reports | minio or external endpoint |
All three must be backed up together for a consistent restore. A backup of MongoDB alone is not sufficient if object-storage artifacts are referenced in the scan records.
MongoDB
Backup
The mongodump utility produces a compressed archive of the database. Run it from a pod that can reach the MongoDB service, or from your operator workstation if kubectl port-forward is active.
# Option A: run inside the mongodb pod
kubectl -n plexicus exec deploy/mongodb -- mongodump \
--uri "mongodb://root:${DATABASE_PASSWORD}@localhost:27017/plexicus?authSource=admin" \
--gzip \
--archive=/tmp/plexicus-mongo-$(date +%Y%m%d-%H%M%S).archive
# Copy the archive to your workstation
kubectl -n plexicus cp \
mongodb-<pod-suffix>:/tmp/plexicus-mongo-<timestamp>.archive \
./plexicus-mongo-$(date +%Y%m%d).archive
Replace ${DATABASE_PASSWORD} with the value stored in the DATABASE_PASSWORD key of the plexicus-fastapi or plexicus-worker Secret:
kubectl -n plexicus get secret plexicus-fastapi \
-o jsonpath='{.data.DATABASE_PASSWORD}' | base64 -d
Daily backups with a 7-day retention window are a reasonable baseline. Increase frequency before planned upgrades or periods of heavy scanning activity.
Restore
# Copy the archive into the pod
kubectl -n plexicus cp ./plexicus-mongo-<timestamp>.archive \
deploy/mongodb:/tmp/restore.archive
# Restore from the archive
kubectl -n plexicus exec deploy/mongodb -- mongorestore \
--uri "mongodb://root:${DATABASE_PASSWORD}@localhost:27017/?authSource=admin" \
--gzip \
--archive=/tmp/restore.archive \
--drop # drops existing collections before restoring — omit to merge
Validation: after restore, confirm the expected document counts in the key collections:
kubectl -n plexicus exec deploy/mongodb -- mongosh \
"mongodb://root:${DATABASE_PASSWORD}@localhost:27017/plexicus?authSource=admin" \
--quiet --eval '
printjson({
Users: db.Users.countDocuments(),
Findings: db.Findings.countDocuments(),
})
'
Compare the counts to the values captured before the backup was taken.
PostgreSQL (Temporal)
Temporal uses PostgreSQL for workflow history and visibility. Back up both databases.
Backup
# Backup the temporal database
kubectl -n plexicus exec deploy/temporal-postgresql-0 -- \
pg_dump -U postgres -Fc temporal \
> temporal-$(date +%Y%m%d).dump
# Backup the temporal_visibility database
kubectl -n plexicus exec deploy/temporal-postgresql-0 -- \
pg_dump -U postgres -Fc temporal_visibility \
> temporal_visibility-$(date +%Y%m%d).dump
The temporal-postgresql pod name depends on whether it is running as a StatefulSet (bundled subchart) or a Deployment. Adjust the exec target accordingly: statefulset/temporal-postgresql or deploy/temporal-postgresql.
Restore
kubectl -n plexicus exec -i deploy/temporal-postgresql-0 -- \
pg_restore -U postgres -d temporal --clean < temporal-<timestamp>.dump
kubectl -n plexicus exec -i deploy/temporal-postgresql-0 -- \
pg_restore -U postgres -d temporal_visibility --clean \
< temporal_visibility-<timestamp>.dump
Object Storage
Backup with MinIO Client (mc)
If you use the bundled MinIO subchart, use mc mirror to replicate the bucket to a secondary location:
# Configure the MinIO Client to point at the in-cluster service
# (run from a pod with network access, or via kubectl port-forward)
mc alias set local http://minio:9000 <rootUser> <rootPassword>
# Mirror the bucket to a backup destination (another S3-compatible endpoint)
mc mirror local/platform s3-backup/<backup-bucket-name>/$(date +%Y%m%d)/
Backup with an external S3 provider
If you use an external S3-compatible provider, use your provider's native snapshot or bucket-replication feature. The key bucket names are set in global.required.minio.buckets in your values overlay.
For provider-level snapshots, consult your S3 provider's documentation. Replication to a second bucket or region is strongly recommended for production.
Sealed Secrets Sealing Key
If you use Sealed Secrets, the controller sealing key is not a database backup — but losing it is as catastrophic as losing your database: every SealedSecret becomes permanently unreadable.
Back up the key immediately after installing the controller and after every key rotation:
kubectl -n kube-system get secret \
-l sealedsecrets.bitnami.com/sealed-secrets-key \
-o yaml > sealed-secrets-key.backup.yaml
# Store offline — never commit to Git.
To restore the key to a replacement cluster, apply the backup YAML before the sealed-secrets controller starts, so the controller picks up the existing key rather than generating a new one. Then apply your SealedSecret manifests as normal.
Pre-Upgrade Backup Procedure
Run the following sequence immediately before any helm upgrade:
# 1. MongoDB
kubectl -n plexicus exec deploy/mongodb -- mongodump \
--uri "mongodb://root:<password>@localhost:27017/plexicus?authSource=admin" \
--gzip --archive=/tmp/pre-upgrade-mongo.archive
kubectl -n plexicus cp mongodb-<pod>:/tmp/pre-upgrade-mongo.archive \
./pre-upgrade-mongo-$(date +%Y%m%d-%H%M).archive
# 2. PostgreSQL
kubectl -n plexicus exec deploy/temporal-postgresql-0 -- \
pg_dump -U postgres -Fc temporal > pre-upgrade-temporal-$(date +%Y%m%d).dump
# 3. Object storage snapshot (provider-specific or mc mirror)
# 4. Note the current Helm revision (for rollback reference)
helm history plexicus -n plexicus | tail -1
With these backups in hand, you can safely proceed with helm upgrade. If something goes wrong after the upgrade, use helm rollback plexicus -n plexicus to restore the chart state, and restore the databases from the backups above if data inconsistencies are detected.