diff --git a/self-hosting-helm.mdx b/self-hosting-helm.mdx index 73725a3..29f0f40 100644 --- a/self-hosting-helm.mdx +++ b/self-hosting-helm.mdx @@ -322,6 +322,10 @@ The chart will automatically run database migrations before deploying the new ve ## Backup and restore + + These steps cover PostgreSQL backups and restore. They do not automatically back up or restore uploaded files if your deployment stores them outside PostgreSQL. + + ### PostgreSQL backups with CloudNativePG CloudNativePG supports volume snapshot backups: @@ -352,14 +356,24 @@ kubectl exec -n sure $PRIMARY_POD -- pg_dump -U sure sure_production > backup.sq ### Restore from backup +1. Make sure app traffic is stopped or the deployment is in maintenance mode. + +2. Copy the SQL backup to the primary PostgreSQL pod: + ```bash -# Copy backup to pod kubectl cp backup.sql sure/$PRIMARY_POD:/tmp/backup.sql +``` + +3. Restore the database: -# Restore +```bash kubectl exec -n sure $PRIMARY_POD -- psql -U sure sure_production -f /tmp/backup.sql ``` +4. If your deployment uses uploaded files stored outside PostgreSQL, restore those separately using the matching volume snapshot or object-storage recovery process. + +5. Verify that the app starts cleanly and your data appears as expected. + ## Troubleshooting ### View logs diff --git a/self-hosting.mdx b/self-hosting.mdx index 5360893..accd7c8 100644 --- a/self-hosting.mdx +++ b/self-hosting.mdx @@ -221,6 +221,20 @@ docker compose up --no-deps -d web worker The Docker Compose configuration includes an optional backup service that automatically backs up your PostgreSQL database. + + The backup service only creates PostgreSQL backups. It does not back up local files stored in Sure's `storage` directory. + If your deployment uses local file storage, back up that directory separately. If you use external object storage such as S3 or R2, make sure that storage is protected with its own backup and retention policy. + + +### What to back up + +For a complete recovery plan, make sure you know which of these apply to your deployment: + +- **PostgreSQL database**: accounts, transactions, settings, users, and metadata +- **Local file storage**: uploaded files stored on disk by the app +- **External object storage**: uploaded files stored in S3, R2, or another object store +- **Environment and deployment config**: your `.env`, `compose.yml`, secrets, and any reverse proxy or DNS setup needed to bring the app back online + ### Enabling backups The backup service uses Docker Compose profiles and is disabled by default. To enable it: @@ -268,28 +282,56 @@ You can use cron syntax or these shortcuts: - `@monthly` - Once per month - Custom cron: `0 2 * * *` (2 AM daily) -### Restoring from backup +### Restore from a PostgreSQL backup -To restore your database from a backup: +Use this process when you have a SQL dump created by the backup service or with `pg_dump`. + +> [!NOTE] +> If you customized the PostgreSQL username, password, or database name in your `.env` or `compose.yml`, replace `sure_user` and `sure_production` in the commands below. + +1. Stop the application containers so they do not write to the database during the restore: -1. Stop the application: ```bash -docker compose down +docker compose stop web worker ``` -2. Locate your backup file in the backup directory (e.g., `/opt/sure-data/backups`) +2. Start or keep the database container running: -3. Restore the backup: ```bash docker compose up -d db +``` + +3. Locate the backup file in your backup directory, for example `/opt/sure-data/backups`. + +4. Restore the SQL backup into PostgreSQL: + +```bash docker compose exec -T db psql -U sure_user -d sure_production < /path/to/backup.sql ``` -4. Restart the application: +5. Restart the app: + ```bash -docker compose up -d +docker compose up -d web worker ``` +### Restore local uploaded files + +If your Sure instance stores uploaded files on the local filesystem, restoring the database alone is not enough. You must also restore the app's storage directory from the matching file backup. + +The exact host path depends on how you mapped volumes in `compose.yml`. Restore the same directory that Sure uses for local storage, then restart the app containers. + +If you are using external object storage instead of local disk, restore those files using that provider's backup or versioning workflow instead. + +### Verify the restore + +After restoring, check the following: + +- You can sign in successfully +- Your accounts and transactions appear as expected +- Uploaded files open correctly, if you use uploads +- The web and worker containers start cleanly without repeated errors + ### Verifying backups Check that backups are running correctly: