# Backup & Recovery Protecting your Likwid data. ## What to Backup | Component | Location | Priority | | ----------- | -------- | -------- | | PostgreSQL database | Database server | Critical | | Uploaded files | `/uploads` (if configured) | High | | Configuration | `.env` files | High | | SSL certificates | Reverse proxy | Medium | ## Database Backup Likwid's recommended backup mechanism is a logical PostgreSQL dump (via `pg_dump`). ### Where backups live (recommended) Store backups under the deploy user, next to the repo: ```bash mkdir -p ~/likwid/backups ``` Retention guidance: - Keep at least 7 daily backups. - For production instances, also keep at least 4 weekly backups. - Keep at least one offsite copy. ### Backup now (containerized, recommended) #### Production compose (`compose/production.yml`) The production database container is named `likwid-prod-db`. ```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 ``` #### Demo compose (`compose/demo.yml`) The demo database container is named `likwid-demo-db`. ```bash 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 ``` #### 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`. ## Recovery ### Restore into a fresh environment (containerized) This procedure is designed to work for a brand new server (or a clean slate on the same server). 1. Ensure you have backups of: - `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. ### 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 ``` 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. ## Disaster Recovery Plan ### Preparation 1. Document backup procedures 2. Test restores regularly (monthly) 3. Keep offsite backup copies 4. Document recovery steps ### Recovery Steps 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) Target: 4 hours for full recovery ### Recovery Point Objective (RPO) Target: 24 hours of data loss maximum (with daily backups) ## Testing Backups Monthly backup test procedure: 1. Create test database 2. Restore backup to test database 3. Run verification queries 4. Document results 5. Delete test database