> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neobank.proofof.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Backups & recovery

> Vault, PostgreSQL, Redis, and Caddy certificates live in named volumes. Back up vault-data, vault-bootstrap, and postgres-data together, and never run --volumes against an active connection.

# 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:

```bash theme={null}
make server-down
make server-up
```

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.

<Note title="What restart recovery does and does not do">
  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](operate/operator-required-cleanup).
</Note>

## The backup set

Back up three volumes **together** as one consistent set:

| Volume            | Holds                                                            |
| ----------------- | ---------------------------------------------------------------- |
| `vault-data`      | Vault's sealed data, including stored Perflo ciphertext          |
| `vault-bootstrap` | Vault unseal and root-recovery material                          |
| `postgres-data`   | PostgreSQL — customers, connections, mandates, operations, audit |

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.

<Warning title="Take them as a set">
  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.
</Warning>

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

<Warning title="Never --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.
</Warning>

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:

```bash theme={null}
make server-down
```

If a connection is pending or requires operator action at retirement time, follow
[Operator-required cleanup](operate/operator-required-cleanup) before destroying any volume.

## Related

* [Operator-required cleanup](operate/operator-required-cleanup) — the workflow that must run
  before a connection row can be safely deleted, and the prerequisite backup this page
  describes.
* [Vault](deploy/vault) — Vault deployment, the Transit key, and the bootstrap sidecar.
* [Dedicated server](deploy/dedicated-server) — the Compose stacks behind
  `make server-up` and `make server-down`.
