2026-01-27 16:21:58 +00:00
# Backup & Recovery
Protecting your Likwid data.
## What to Backup
| Component | Location | Priority |
2026-02-16 10:26:37 +00:00
| ----------- | -------- | -------- |
2026-01-27 16:21:58 +00:00
| PostgreSQL database | Database server | Critical |
| Uploaded files | `/uploads` (if configured) | High |
| Configuration | `.env` files | High |
| SSL certificates | Reverse proxy | Medium |
## Database Backup
2026-02-16 10:26:37 +00:00
Likwid's recommended backup mechanism is a logical PostgreSQL dump (via `pg_dump` ).
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
### Where backups live (recommended)
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
Store backups under the deploy user, next to the repo:
2026-01-27 16:21:58 +00:00
```bash
2026-02-16 10:26:37 +00:00
mkdir -p ~/likwid/backups
```
Retention guidance:
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
- Keep at least 7 daily backups.
- For production instances, also keep at least 4 weekly backups.
- Keep at least one offsite copy.
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
### Backup now (containerized, recommended)
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
#### Production compose (`compose/production.yml`)
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
The production database container is named `likwid-prod-db` .
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
```bash
ts=$(date +%Y%m%d_%H%M%S)
podman exec -t likwid-prod-db pg_dump -U likwid -F c -d likwid_prod > ~/likwid/backups/likwid_prod_${ts}.dump
2026-01-27 16:21:58 +00:00
```
2026-02-16 10:26:37 +00:00
#### Demo compose (`compose/demo.yml`)
The demo database container is named `likwid-demo-db` .
2026-01-27 16:21:58 +00:00
```bash
2026-02-16 10:26:37 +00:00
ts=$(date +%Y%m%d_%H%M%S)
podman exec -t likwid-demo-db pg_dump -U likwid_demo -F c -d likwid_demo > ~/likwid/backups/likwid_demo_${ts}.dump
2026-01-27 16:21:58 +00:00
```
2026-02-16 10:26:37 +00:00
#### Notes
- The `-F c` format is recommended because it is compact and supports `pg_restore --clean` .
- If you are using a shell that does not handle binary stdout redirection well, write the dump inside the container and use `podman cp` .
2026-01-27 16:21:58 +00:00
## Recovery
2026-02-16 10:26:37 +00:00
### Restore into a fresh environment (containerized)
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
This procedure is designed to work for a brand new server (or a clean slate on the same server).
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
1. Ensure you have backups of:
2026-01-27 16:21:58 +00:00
2026-02-16 10:26:37 +00:00
- `compose/.env.production` (or `compose/.env.demo` )
- Reverse proxy config
- The database dump file (`*.dump`)
1. If you are restoring over an existing instance, stop the stack.
Production:
```bash
cd ~/likwid
podman compose --env-file compose/.env.production -f compose/production.yml down
```
Demo:
```bash
cd ~/likwid
podman compose --env-file compose/.env.demo -f compose/demo.yml -f compose/demo.vps.override.yml down
```
1. If you need an empty database, remove the database volume (destructive).
Production (removes the `likwid_prod_data` volume):
```bash
cd ~/likwid
podman compose --env-file compose/.env.production -f compose/production.yml down -v
```
Demo (removes the `likwid_demo_data` volume):
```bash
cd ~/likwid
podman compose --env-file compose/.env.demo -f compose/demo.yml -f compose/demo.vps.override.yml down -v
```
1. Start only the database container so Postgres recreates the database.
Production:
```bash
cd ~/likwid
podman compose --env-file compose/.env.production -f compose/production.yml up -d postgres
```
Demo:
```bash
cd ~/likwid
podman compose --env-file compose/.env.demo -f compose/demo.yml -f compose/demo.vps.override.yml up -d postgres
```
1. Restore from the dump:
- Production restore:
```bash
podman exec -i likwid-prod-db pg_restore -U likwid -d likwid_prod --clean --if-exists < /path/to/likwid_prod_YYYYMMDD_HHMMSS.dump
```
- Demo restore:
```bash
podman exec -i likwid-demo-db pg_restore -U likwid_demo -d likwid_demo --clean --if-exists < /path/to/likwid_demo_YYYYMMDD_HHMMSS.dump
```
1. Verify the restore:
```bash
podman exec -t likwid-prod-db psql -U likwid -d likwid_prod -c "SELECT now();"
```
1. Start the full stack again (backend + frontend):
Production:
```bash
cd ~/likwid
podman compose --env-file compose/.env.production -f compose/production.yml up -d
```
Demo:
```bash
cd ~/likwid
podman compose --env-file compose/.env.demo -f compose/demo.yml -f compose/demo.vps.override.yml up -d
```
### Restore notes
- `pg_restore --clean --if-exists` drops existing objects before recreating them.
- If you are restoring between different versions, run the matching app version first, then upgrade normally.
2026-01-27 16:21:58 +00:00
### Point-in-Time Recovery
For critical installations, configure PostgreSQL WAL archiving:
```ini
# postgresql.conf
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/archive/%f'
```
## Demo Instance Reset
The demo instance can be reset to initial state:
```bash
# Windows
.\scripts\demo-reset.ps1
# Linux
./scripts/demo-reset.sh
```
2026-02-16 10:26:37 +00:00
This is destructive and removes all demo data by recreating the demo database volume; on startup the backend runs core migrations and demo seed migrations to restore the initial demo dataset. This is not a backup mechanism.
2026-01-27 16:21:58 +00:00
## Disaster Recovery Plan
### Preparation
2026-02-16 10:26:37 +00:00
2026-01-27 16:21:58 +00:00
1. Document backup procedures
2. Test restores regularly (monthly)
3. Keep offsite backup copies
4. Document recovery steps
### Recovery Steps
2026-02-16 10:26:37 +00:00
2026-01-27 16:21:58 +00:00
1. Provision new server if needed
2. Install Likwid dependencies
3. Restore database from backup
4. Restore configuration files
5. Start services
6. Verify functionality
7. Update DNS if server changed
### Recovery Time Objective (RTO)
2026-02-16 10:26:37 +00:00
2026-01-27 16:21:58 +00:00
Target: 4 hours for full recovery
### Recovery Point Objective (RPO)
2026-02-16 10:26:37 +00:00
2026-01-27 16:21:58 +00:00
Target: 24 hours of data loss maximum (with daily backups)
## Testing Backups
Monthly backup test procedure:
2026-02-16 10:26:37 +00:00
2026-01-27 16:21:58 +00:00
1. Create test database
2. Restore backup to test database
3. Run verification queries
4. Document results
5. Delete test database