Skip to content

Backups and Migration Safety

delabrcd edited this page Jun 6, 2026 · 1 revision

Backups and Migration-Safety

The app keeps its schema in sync at startup with prisma db push --accept-data-loss — no migration files, no rollback. That's convenient but dangerous: a destructive schema change would silently drop production rows on the next deploy. Two independent guards protect against that.

Guard 1 — pre-upgrade pg_dump backup (on-host, fail-closed)

The deploy entrypoint (app/docker-entrypoint.sh) checks whether the live DB schema already matches before pushing:

  • In sync → logs schema already in sync — no pre-migrate backup needed and skips straight to starting the app.
  • Schema change detected → logs schema change detected — backing up database to …, writes a gzipped pg_dump to BACKUP_DIR, and only then applies the db push. If that backup cannot be written, it refuses to migrate (fail-closed) — there's always a restore point.

Config (.env):

Var Default Meaning
BACKUP_DIR ./data/backups Host dir for the dumps (browse/copy them directly).
BACKUP_BEFORE_MIGRATE true Take the pre-upgrade backup (false skips — not recommended).
BACKUP_RETENTION 10 Keep the newest N dumps; older are pruned.

The standalone compose mounts BACKUP_DIR to /data/backups (a backups host bind alongside the PDFs). Restore one with:

gunzip -c ./data/backups/ngrid-pre-migrate-<stamp>.sql.gz \
  | docker compose exec -T ngrid_postgres psql -U ngrid -d ngrid

Guard 2 — migration-safety CI gate (catches it before it ships)

The backup is a safety net; the CI job stops a destructive change from ever reaching a deploy. In docker-publish.yml, the migration-safety job:

  1. Resolves the previous release tag and reads its schema (git show <prev-tag>:app/prisma/schema.prisma).
  2. Seeds a Postgres 16 service with that old schema and representative data.
  3. Applies the current schema and asserts data is preserved (.github/migration-safety/check.sh).
  4. Skips automatically when there's no prior release tag (nothing to upgrade from).

build-push needs: [test, migration-safety], so the image won't publish unless this passes (and the test unit suite — see Testing). Together: CI proves the upgrade is non-destructive, the entrypoint backup is the on-host last resort. See Releases and CI.

Clone this wiki locally