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

87 lines
2.0 KiB
Markdown

# 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:
```bash
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
```bash
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:
```bash
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:
```bash
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:
```bash
pnpm db:restore:prod -- local/backups/<file>.dump
```
Run a non-destructive restore test into a temporary DB:
```bash
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