Files
ginnoir c73338e256 Code-side
src/lib/dev-login-config.ts — startup assertion: throws if NODE_ENV=production + ENABLE_DEV_LOGIN=true, scoped to runtime (skipped during next build).
Container

scripts/migrate.mjs — runs Drizzle migrations against DATABASE_URL.
deploy/docker-entrypoint.sh — runs migrations then exec node server.js. Skip with RUN_MIGRATIONS=false.
Dockerfile — copies drizzle/, scripts/migrate.mjs, entrypoint into runner stage; ENTRYPOINT now points at the script.
Compose

deploy/compose.yaml — famapp now image: ${FAMAPP_IMAGE:-ghcr.io/ginnoir/famapp:latest} (build still works locally as fallback). Authentik pinned via AUTHENTIK_IMAGE_TAG (default 2024.12.3). New RUN_MIGRATIONS env passed through.
.env.production.example — documents FAMAPP_IMAGE, AUTHENTIK_IMAGE_TAG, RUN_MIGRATIONS.
CI/CD

.github/workflows/ci.yml — push/PR: typecheck + lint + format:check + build.
.github/workflows/release.yml — v* tag: build + push ghcr.io/ginnoir/famapp:vX.Y.Z, :X.Y, :latest to GHCR.
Docs

deploy/README.md — full deploy/rollback/release runbook.
CHANGELOG.md — release log seeded with an Unreleased entry.
docs/tasks/09-pre-deploy-checklist.md — task 09 reframed from one-shot removal to a recurring pre-deploy checklist.
STATUS.md — updated.
Verified: pnpm typecheck, pnpm format, pnpm build, and docker compose config all clean.
2026-05-06 17:37:37 -05:00

103 lines
2.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Backups
The `famapp-backup` service performs nightly compressed `pg_dump` of both
`famapp-db` and `authentik-db` at **02:00 server time**.
## Storage layout
```
/backups/ (named Docker volume: famapp_backups)
famapp/
daily/ ← last 14 days
weekly/ ← last 8 Sundays
monthly/ ← last 6 first-of-month dumps
authentik/
daily/
weekly/
monthly/
```
Dump files are named `YYYY-MM-DD.dump` in custom (`-Fc`) format (internal
compression, ~35× smaller than plain SQL).
## Retention
| Tier | Kept | Trigger |
| ------- | ---- | ---------------- |
| daily | 14 | every night |
| weekly | 8 | Sunday night |
| monthly | 6 | 1st of the month |
Retention is enforced by `retain.sh` at the end of each `backup.sh` run.
## Restore procedure
### 1. Identify the dump
```sh
# List available dumps
docker exec famapp-backup-1 ls /backups/famapp/daily/
```
### 2a. Restore inside the backup container (recommended)
```sh
docker exec famapp-backup-1 /scripts/restore.sh \
/backups/famapp/daily/2024-06-01.dump \
postgres://famapp:SECRET@famapp-db:5432/famapp
```
Replace `SECRET` with the value of `FAMAPP_DB_PASSWORD` in your `.env` file.
For authentik:
```sh
docker exec famapp-backup-1 /scripts/restore.sh \
/backups/authentik/daily/2024-06-01.dump \
postgres://authentik:SECRET@authentik-db:5432/authentik
```
### 2b. Restore to a separate database (safe — non-destructive)
Create a fresh target database first, then restore into it:
```sh
# Create the target DB
docker exec famapp-db-1 createdb \
-U "$FAMAPP_DB_USER" famapp_restore
# Restore
docker exec famapp-backup-1 /scripts/restore.sh \
/backups/famapp/daily/2024-06-01.dump \
postgres://famapp:SECRET@famapp-db:5432/famapp_restore
```
### 2c. Restore on a fresh host (disaster recovery)
```sh
# Copy the dump file out of the volume
docker cp famapp-backup-1:/backups/famapp/daily/2024-06-01.dump ./
# Spin up a temporary Postgres container and restore
docker run --rm \
-e PGPASSWORD=SECRET \
-v "$(pwd)/2024-06-01.dump:/dump.dump:ro" \
postgres:16-alpine \
pg_restore -h <new-db-host> -U famapp -d famapp \
--no-owner --no-acl /dump.dump
```
## Off-site replication
The backups live in the `famapp_backups` Docker named volume. To copy them
to another host, rsync the volume's data directory periodically (e.g. from a
host cron job):
```sh
# On the Docker host, add to /etc/cron.d/famapp-rsync:
30 3 * * * root rsync -a --delete \
/var/lib/docker/volumes/famapp_backups/_data/ \
user@offsite-server:/opt/famapp-backups/
```
Encryption at rest is handled at the disk/filesystem layer (e.g. LUKS).