mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
Add WHOOP as a synced provider (per-user BYO-keys OAuth2 + HMAC-signed webhooks), the longitudinal coach (narrative + per-metric trajectory), and the read-only FHIR R4 REST API plus the scoped, time-limited clinician share-link record across README, the self-hosting and ops runbooks, and a new WHOOP integration page. Note the two optional WHOOP instance env vars, that migrations 0110-0114 are additive, and the two known limitations (dual-source standard-vital dedup deferred; coach durable-memory deferred). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
93 lines
3.8 KiB
Markdown
93 lines
3.8 KiB
Markdown
# Deploy ordering
|
||
|
||
Coolify handles the standard deploy ordering automatically: the
|
||
container image is pulled, `docker-entrypoint.sh` runs
|
||
`prisma migrate deploy` against the live database, and only then does
|
||
the Next.js process bind to the listener. This page documents the
|
||
ordering explicitly for manual-rollback and partial-deploy scenarios
|
||
where the operator drives the steps by hand.
|
||
|
||
## Migration ordering
|
||
|
||
Migrations land **before** the new app container takes traffic. The
|
||
canonical command sequence on a single-instance host:
|
||
|
||
```sh
|
||
# 1. Pull the new image.
|
||
docker pull ghcr.io/mbombeck/healthlog:vX.Y.Z
|
||
|
||
# 2. Run migrations against the live DB using the new image.
|
||
docker run --rm --env-file .env.production \
|
||
ghcr.io/mbombeck/healthlog:vX.Y.Z \
|
||
pnpm prisma migrate deploy
|
||
|
||
# 3. Recreate the app container so it picks up the new image.
|
||
docker compose up -d app
|
||
```
|
||
|
||
The entrypoint also runs `prisma migrate deploy` on container boot, so
|
||
step 2 is redundant in normal Coolify flow. It's listed explicitly for
|
||
the manual case so an operator can verify the migration result before
|
||
flipping traffic.
|
||
|
||
### v1.11.0 notes
|
||
|
||
Migrations `0110`–`0114` are additive (new tables / columns for the
|
||
WHOOP provider hub, the longitudinal coach, and the clinician FHIR
|
||
record). They require no special steps — `prisma migrate deploy` runs
|
||
them in order on boot like any other.
|
||
|
||
WHOOP introduces two optional instance env vars, `WHOOP_REDIRECT_URI`
|
||
and `WHOOP_WEBHOOK_SECRET` (HMAC secret for WHOOP webhook signature
|
||
verification). Per-user WHOOP client id/secret live in Settings, not
|
||
in the environment. See `docs/integrations/whoop.md`. Add the two vars
|
||
to the compose `environment:` whitelist if you set them — vars not on
|
||
the whitelist never reach the container.
|
||
|
||
### What goes wrong if you reverse it
|
||
|
||
If the new app container starts before migrations run, the legacy
|
||
schema is missing the columns / indexes / enum values the new code
|
||
expects. Symptoms: Prisma client throws `P2022 column does not exist`
|
||
on the first query that touches the new shape, the request path 500s,
|
||
and the dispatcher logs fill with the same error until the migration
|
||
catches up. Health checks usually keep the container marked "healthy"
|
||
because `/api/version` doesn't exercise the affected tables — so a
|
||
naïve load balancer will happily route real traffic into the broken
|
||
shell.
|
||
|
||
### Rollback
|
||
|
||
Rolling back **migrations** is generally one-way. Prisma's migration
|
||
history table tracks applied migrations by hash; the `down` step is
|
||
not auto-generated and most HealthLog migrations are forward-only
|
||
(column drops, enum additions, index rebuilds). If a release has to
|
||
roll back:
|
||
|
||
1. Roll back the **app container** to the previous image tag.
|
||
2. Leave the **database schema** at the newer migration. The previous
|
||
app version reads forward-compatible-ish shapes for nearly every
|
||
release pair shipped on the v1.4.x line.
|
||
3. If a column-drop migration ships in the rollback target, hand-roll
|
||
the column back via a fresh forward migration (`pnpm prisma migrate
|
||
dev --create-only --name vX_Y_Z_rollback_<col>`), edit the SQL,
|
||
commit, and re-deploy. Never `migrate resolve --rolled-back` against
|
||
production unless you've taken a fresh `pg_dump` first.
|
||
|
||
## Verify the served version
|
||
|
||
The queued-deploy status is **not** the source of truth — the version
|
||
`/api/version` actually answers is. A BuildKit layer-cache hit can
|
||
re-ship the prior image even when Coolify reports a clean deploy, so
|
||
always confirm the served build after a deploy:
|
||
|
||
```sh
|
||
# Asserts prod + demo serve 1.9.0, prints each target's buildSha,
|
||
# exits non-zero on a mismatch or timeout after a bounded retry loop.
|
||
pnpm dlx tsx scripts/assert-deploy.ts 1.9.0
|
||
```
|
||
|
||
Pass `--only=prod` / `--only=demo` to check a single target, or
|
||
`--attempts=N --interval=ms` to widen the retry window while a slow
|
||
pull settles.
|