Pular para conteúdo

EPPA Backup and Restore Drill Runbook

This runbook covers the repository-owned local drill for EPPA Postgres and MinIO data. It is designed to prove the backup/restore path with synthetic fixtures and without production credentials.

Safety Model

  • Backup output must be written to EPPA_BACKUP_DIR, and the script refuses any directory inside this Git repository.
  • Restore drill only runs against local service hosts: 127.0.0.1, localhost, postgres, or minio.
  • Restore drill refuses to run when EPPA_ENV or ENVIRONMENT is prod or production.
  • Restore drill requires both explicit non-production flags: EPPA_RESTORE_TARGET=local-drill and EPPA_ALLOW_DESTRUCTIVE_RESTORE=YES_I_UNDERSTAND_NON_PRODUCTION.
  • Synthetic fixtures contain no patient data. They are limited to a probe SQL row and a JSON object labeled as synthetic.

Environment

Default local values match docker-compose.yml:

export EPPA_BACKUP_DIR=/tmp/eppa-backups
export DATABASE_URL='postgresql+psycopg://eppa:eppa_dev_pw_CHANGE_ME@127.0.0.1:5432/eppa'
export EPPA_MINIO_ENDPOINT='http://127.0.0.1:9000'
export EPPA_MINIO_ACCESS_KEY='eppa_minio_admin'
export EPPA_MINIO_SECRET_KEY='eppa_minio_dev_pw_CHANGE_ME'
export EPPA_MINIO_BUCKET='eppa-restore-drill'

Use deployment secrets only on the server and never paste them into issues, PRs, logs, or committed files.

Dry Run

Dry run validates output placement and writes only synthetic placeholders:

cd fronts/eppa
EPPA_BACKUP_DIR=/tmp/eppa-backups \
  python3 scripts/backup_restore_drill.py --dry-run backup

For the restore safety path:

cd fronts/eppa
EPPA_BACKUP_DIR=/tmp/eppa-backups \
EPPA_ENV=test \
EPPA_RESTORE_TARGET=local-drill \
EPPA_ALLOW_DESTRUCTIVE_RESTORE=YES_I_UNDERSTAND_NON_PRODUCTION \
  python3 scripts/backup_restore_drill.py --dry-run restore-drill

Local Restore Drill

Start fresh local services:

cd fronts/eppa
docker compose up -d postgres minio
docker compose ps postgres minio

Load the synthetic drill dataset:

EPPA_BACKUP_DIR=/tmp/eppa-backups \
EPPA_ENV=test \
EPPA_RESTORE_TARGET=local-drill \
EPPA_ALLOW_DESTRUCTIVE_RESTORE=YES_I_UNDERSTAND_NON_PRODUCTION \
DATABASE_URL='postgresql+psycopg://eppa:eppa_dev_pw_CHANGE_ME@127.0.0.1:5432/eppa' \
EPPA_MINIO_ENDPOINT='http://127.0.0.1:9000' \
EPPA_MINIO_ACCESS_KEY='eppa_minio_admin' \
EPPA_MINIO_SECRET_KEY='eppa_minio_dev_pw_CHANGE_ME' \
EPPA_MINIO_BUCKET='eppa-restore-drill' \
  python3 scripts/backup_restore_drill.py restore-drill

The command creates or updates eppa_restore_drill_probe in Postgres and uploads restore-drill/synthetic-eppa-minio-001.json to the configured MinIO bucket.

Backup

Run a local backup into an external directory:

cd fronts/eppa
EPPA_BACKUP_DIR=/tmp/eppa-backups \
DATABASE_URL='postgresql+psycopg://eppa:eppa_dev_pw_CHANGE_ME@127.0.0.1:5432/eppa' \
EPPA_MINIO_ENDPOINT='http://127.0.0.1:9000' \
EPPA_MINIO_ACCESS_KEY='eppa_minio_admin' \
EPPA_MINIO_SECRET_KEY='eppa_minio_dev_pw_CHANGE_ME' \
EPPA_MINIO_BUCKET='eppa-restore-drill' \
  python3 scripts/backup_restore_drill.py backup

Each run creates a timestamped directory containing:

  • postgres.dump: pg_dump --format=custom output.
  • minio/: downloaded MinIO object files for the configured bucket/prefix.
  • postgres-synthetic.sql and minio-synthetic-object.json: non-sensitive fixtures used by the drill.
  • manifest.json: operation metadata and a contains_real_patient_data: false declaration for the synthetic fixtures.

Retention Assumptions

  • Keep local drill outputs short-lived. Delete /tmp/eppa-backups after the drill unless an audit packet explicitly needs the manifest.
  • Production retention policy is outside this repository-owned script and must be enforced by the production storage target.
  • Do not copy production backup artifacts into the Git repository.