# Backup and Restore (V6.0 Phase 4) This guide defines operational backup/restore for clean-slate recovery of the Docker runtime and Synology replication. ## 1. Backup artifacts (full recovery set) - Primary local backup location: `./data/backups` - Files created per timestamp: - `postgres-YYYYMMDD-HHMMSS.dump` (PostgreSQL custom dump via `pg_dump -Fc`) - `uploads-YYYYMMDD-HHMMSS.tar.gz` (full `/app/uploads` volume; includes `homepage.md`, documents, and photos) - `config-YYYYMMDD-HHMMSS.tar.gz` (deployment config snapshot: `.env.production`, `docker-compose.production.yml`, `deploy/cloudflared/config.yml`) - `backup-YYYYMMDD-HHMMSS.manifest` (artifact index) ## 2. Creating backups Use the scripted command from the repository root: ```bash sh deploy/backup/create_postgres_backup.sh ``` Environment overrides: - `BACKUP_DIR` (default `./data/backups`) - `BACKUP_RETENTION_DAYS` (default `14`) - `SYNOLOGY_BACKUP_DIR` (if set, backup is copied to this mounted path) - `ENV_FILE` (default `.env.production`) - `COMPOSE_FILE` (default `docker-compose.production.yml`) Example with Synology mount: ```bash SYNOLOGY_BACKUP_DIR=/mnt/synology/transcription-backups sh deploy/backup/create_postgres_backup.sh ``` ## 2.1 Persisting Synology mount (LXC) The backup copy step depends on a mounted NAS path. Manual `mount` commands are lost after reboot unless persisted. Use the template (copy, edit placeholders, then run): ```bash cp deploy/backup/mount_synology_cifs.example.sh /root/mount_synology_cifs.sh nano /root/mount_synology_cifs.sh sh /root/mount_synology_cifs.sh ``` Then add the printed `/etc/fstab` line (with your real values) so the mount survives reboot. Recommended pattern: - Keep NAS credentials in a local file like `/etc/samba/credentials/transcription-synology` with `chmod 600`. - Keep `SYNOLOGY_BACKUP_DIR` in `.env.production` aligned to that mount point (for example `/mnt/synology-backups`). ## 3. Restoring from backup Restore requires downtime for app + worker writes. 1. Stop app and worker: - `docker compose --env-file .env.production -f docker-compose.production.yml stop app worker` 2. Restore: - `sh deploy/backup/restore_postgres_backup.sh ./data/backups/postgres-YYYYMMDD-HHMMSS.dump` - if same-timestamp `uploads-*.tar.gz` and `config-*.tar.gz` exist in the same directory, they are restored automatically. 3. Start app and worker: - `docker compose --env-file .env.production -f docker-compose.production.yml start app worker` 4. Validate `/healthz` and run one smoke workflow. Notes: - Config restore extracts the archived files back into the current repository path. - If only the database dump is present, restore runs in database-only mode (legacy behavior). ## 4. Retention and recovery targets - Retention baseline: keep at least 14 days of backups locally. - Synology copy: replicate each backup artifact set to DS420j mounted path. - Periodic restore drill: run at least once per release cycle to verify recovery.