Files
bookorbit/docs/production.md
T
neon a3579ac57f ci: overhaul CI workflows for reliability and maintainability
- add CODEOWNERS assigning .github/ to @neonsolstice
- configure automated updates for npm, docker, and github-actions ecosystems
- replace custom change-detection bash script with dorny/paths-filter@v4
- consolidate lint, typecheck, and test into a single checks matrix job
- gate per-package change detection via has-changes step (matrix unavailable in job-level if)
- fix duplicate actions/setup-node call in setup-node-pnpm composite action
- scope pnpm store cache key by pnpm version to prevent stale cross-version cache hits
- pin all action references to commit SHAs
- fix container-image concurrency group to use commit SHA across all trigger types
- add timeout-minutes to all jobs
- document fail-fast: false rationale and checks: write trade-off
2026-03-07 18:14:36 -06:00

2.0 KiB

Production Deployment (Docker Compose)

This project's production Compose stack is intentionally separate from local development.

1) Configure production environment

Create .env.prod from the example and set real values:

cp .env.prod.example .env.prod

Required fields:

  • APP_IMAGE (immutable tag or digest from CI, for example ghcr.io/<owner>/<repo>:sha-<commit>)
  • POSTGRES_USER
  • POSTGRES_PASSWORD
  • POSTGRES_DB
  • JWT_SECRET
  • APP_URL

2) Deploy

docker compose --env-file .env.prod -f docker-compose.prod.yml pull
docker compose --env-file .env.prod -f docker-compose.prod.yml up -d --wait

What happens:

  • postgres starts with pgvector enabled via init SQL.
  • migrate runs once (node dist/scripts/migrate.js) and must complete successfully.
  • app starts only after DB health is healthy and migration service exits successfully.

3) Roll forward

  1. Update APP_IMAGE in .env.prod to the new immutable image.
  2. Pull + restart:
docker compose --env-file .env.prod -f docker-compose.prod.yml pull
docker compose --env-file .env.prod -f docker-compose.prod.yml up -d --wait

4) Backup strategy

Create a compressed custom-format Postgres backup:

pnpm db:backup:prod

By default this writes to local/backups/.

Recommended cadence:

  • Daily backups
  • Keep at least 7 daily + 4 weekly + 3 monthly snapshots
  • Store a copy off-host

5) Restore strategy

Restore into the live DB:

pnpm db:restore:prod -- local/backups/<file>.dump

Run a non-destructive restore test into a temporary DB:

pnpm db:restore:test:prod -- local/backups/<file>.dump

Run the restore test at least monthly so backup integrity is continuously verified.

6) CI image pipeline

Workflow: .github/workflows/container-image.yml

On main and tag pushes it:

  • builds the Docker image
  • pushes immutable tags to GHCR (sha-*)
  • scans the image with Trivy (high/critical)
  • generates an SPDX SBOM artifact