Skip to main content

Backups & recovery

The platform’s persistent state — Vault data and its unseal material, PostgreSQL, both Redis instances, and the server Caddy certificates — lives in named Docker volumes. A restart that preserves the volumes restores the system to the same state without operator intervention. This page covers the restart-recovery contract and the backup set you must take before any state-affecting maintenance.

Named volumes and restart recovery

The bootstrap sidecar automatically unseals Vault and verifies the same derived Transit key after a container or host restart. Because every persistent artifact is in a named volume, a controlled restart does not lose state:
The equivalent on Kubernetes is to restart the Deployments (or let the cluster recycle the Pods) without deleting the PersistentVolumeClaims. After the restart, sign in again and confirm that each customer still sees only their own onboarding and account state.
Restart recovery restores the local operational state — the Vault-sealed provider credentials, the PostgreSQL ledger rows, and the Redis sessions. It does not change the Perflo provider state. If a provider refresh or cleanup became uncertain before the restart, that customer’s connection is still operator_action_required on the way back up, and the UI still stops offering connection actions. Resolve it through Operator-required cleanup.

The backup set

Back up three volumes together as one consistent set: The bootstrap volume contains unseal and root-recovery material and must receive the same access controls as a secret backup. Losing either Vault volume makes the stored Perflo ciphertext unrecoverable — the data volume holds the ciphertext and the bootstrap volume holds the keys to decrypt it; either one alone is useless.
A backup of postgres-data without the matching Vault volumes is not a valid restore point: the connection rows reference ciphertext the restored PostgreSQL cannot decrypt. A backup of vault-data without vault-bootstrap cannot be unsealed. Snapshot all three in the same backup window and label them together.
The session Redis holds short-lived identity state; losing it forces customers back through sign-in. The task Redis is reconstructible from the transactional outbox and read-only reconciliation state. Losing either does not erase PostgreSQL or Vault state. Caddy certificates on the server auto-renew.

Do not destroy volumes on an active connection

Do not run docker compose down --volumes while any active, pending, or operator_action_required Perflo connection exists. Deleting Vault or PostgreSQL state before confirmed provider revocation can leave an orphaned Perflo device or an untracked approval session on the provider side that you can no longer inspect or revoke from this deployment.
Before planned retirement of the deployment, disconnect every customer’s Perflo account and confirm each disconnection in Perflo. Only then stop containers while preserving state and certificates:
If a connection is pending or requires operator action at retirement time, follow Operator-required cleanup before destroying any volume.
  • Operator-required cleanup — the workflow that must run before a connection row can be safely deleted, and the prerequisite backup this page describes.
  • Vault — Vault deployment, the Transit key, and the bootstrap sidecar.
  • Dedicated server — the Compose stacks behind make server-up and make server-down.