generated from john/python-template
98 lines
4.0 KiB
Markdown
98 lines
4.0 KiB
Markdown
# Backup and Restore (V6.0 Phase 4)
|
|
|
|
This guide defines operational backup/restore for clean-slate recovery of the Docker runtime with host-level backups that Synology Drive can replicate.
|
|
|
|
## 1. Backup artifacts (clean-slate recovery set)
|
|
|
|
- Primary local backup location: `DATABASE_BACKUP_DIR` (recommended production value: `/backup`)
|
|
- Local files created per run:
|
|
- `postgres-YYYYMMDD-HHMMSS.dump` (PostgreSQL custom dump via `pg_dump -Fc`)
|
|
- `backup-YYYYMMDD-HHMMSS.manifest` (artifact index)
|
|
- Optional Synology files created per run (when `SYNOLOGY_BACKUP_DIR` is set):
|
|
- `postgres-YYYYMMDD-HHMMSS.dump` (copied from local)
|
|
- `config-YYYYMMDD-HHMMSS.tar.gz` (deployment config snapshot: `.env.production`, `docker-compose.production.yml`, `deploy/cloudflared/config.yml` when present)
|
|
- `logs-YYYYMMDD-HHMMSS.tar.gz` (snapshot of `/app/data/logs`)
|
|
- `backup-YYYYMMDD-HHMMSS.manifest`
|
|
- Local app-data mirror (updated each run):
|
|
- `data/**`
|
|
- Local incremental media mirror (copied only if missing):
|
|
- `uploads/homepage.md`
|
|
- `uploads/documents/**`
|
|
- `uploads/photos/**`
|
|
|
|
## 2. Creating backups
|
|
|
|
Use the scripted command from the repository root:
|
|
|
|
```bash
|
|
sh deploy/backup/create_postgres_backup.sh
|
|
```
|
|
|
|
Environment overrides:
|
|
|
|
- `BACKUP_DIR` (default `DATABASE_BACKUP_DIR`, then `./data/backups`)
|
|
- `APP_DATA_BACKUP_DIR` (default `${BACKUP_DIR}/data`)
|
|
- `UPLOADS_BACKUP_DIR` (default `${BACKUP_DIR}/uploads`)
|
|
- `BACKUP_RETENTION_DAYS` (default `14`)
|
|
- `SYNOLOGY_BACKUP_DIR` (if set, dump/config/log/manifest are copied to this mounted path and media is synced incrementally)
|
|
- `ENV_FILE` (default `.env.production`)
|
|
- `COMPOSE_FILE` (default `docker-compose.production.yml`)
|
|
|
|
Recommended production setup:
|
|
|
|
- Mount a host-visible folder into `/backup` for both `app` and `worker` services.
|
|
- Set `DATABASE_BACKUP_DIR=/backup` in `.env.production`.
|
|
- Leave `SYNOLOGY_BACKUP_DIR` empty when Synology Drive Client handles replication from the host folder.
|
|
|
|
Example with Synology mount:
|
|
|
|
```bash
|
|
SYNOLOGY_BACKUP_DIR=/mnt/synology-backups sh deploy/backup/create_postgres_backup.sh
|
|
```
|
|
|
|
## 2.1 Optional direct Synology mount (LXC)
|
|
|
|
This section is only needed when using direct container-side Synology copy via `SYNOLOGY_BACKUP_DIR`.
|
|
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`).
|
|
- The script will also read `SYNOLOGY_BACKUP_DIR` from `ENV_FILE` when not exported in the shell.
|
|
|
|
## 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 `SYNOLOGY_BACKUP_DIR/uploads` exists, media is restored from the Synology mirror.
|
|
- if `SYNOLOGY_BACKUP_DIR/config-YYYYMMDD-HHMMSS.tar.gz` exists, config is restored from that archive.
|
|
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.
|
|
- Legacy full-archive restores (`uploads-*.tar.gz`, `config-*.tar.gz` beside the dump) are still supported for older backups.
|
|
|
|
## 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.
|