fix(deploy): give migrate the API's client-address settings, and say what Doctor checked #57

Merged
Zayin_Admin merged 2 commits from fix/doctor-client-address into main 2026-10-06 01:18:19 +00:00
Member

fix(deploy): give migrate the API's client-address settings, and say what Doctor checked

Cause of the production report. Doctor said "Direct client-address mode" while the running api had EKKLESIA_CLIENT_ADDRESS_MODE=trusted-proxy.

  • Doctor checks the client-address configuration of the process it runs in.
  • Operators run it as migrate.
  • compose.proxy.yaml gave the three trusted-proxy variables to api only.

Doctor therefore validated an empty configuration and reported direct mode for an installation that trusts its proxy.

Commits

  1. Failing tests first. On main:
    • tests/deploy.test.ts: migrate gets no client-address environment;
    • core/tests/doctor.test.ts: the check does not say whose configuration it read;
    • scripts/smoke-deploy.sh: Doctor through the proxy overlay must report Trusted-proxy client-address mode. Not run against main (Docker); it follows from the static test.
  2. The fix.
Change Why
compose.proxy.yaml: the variables are defined once as a YAML anchor and applied to api and migrate Doctor checks what the API runs. Rendered with docker compose config: api is byte-for-byte unchanged, and migrate matches it, keeping NODE_EXTRA_CA_CERTS from the base
env/compose.env.example: COMPOSE_FILE=compose.yaml:compose.proxy.yaml The README's plain docker compose run --rm migrate … read compose.yaml alone, so even with the overlay fixed Doctor would not have seen it. This is what the instance's deploy/.env already does
Doctor's client-address check, every outcome, gets one more detail line It says it checked the environment Doctor runs with, and how to read the running API's own value: docker compose exec api printenv EKKLESIA_CLIENT_ADDRESS_MODE (confirmed to work in the image)
deploy/README.md Run operator commands with the same Compose files as the stack, and why it matters for Doctor

Verification

  • pnpm verify: passes.
  • bash scripts/smoke-deploy.sh (same-origin, Docker): passes, including ok Doctor: READY, verify-full with the private CA, storage reachable, the API's client-address mode, no secret printed.

The five Biome warnings in tests/deploy.test.ts (noTemplateCurlyInString on Compose ${…} strings) are pre-existing and unchanged.

For the instance

The instance vendors deploy/ verbatim, and its deploy/.env already sets COMPOSE_FILE with the proxy overlay. After the platform pin bump and scripts/vendor-deploy.sh, its documented Doctor command reports trusted-proxy mode with no other change.

🤖 Generated with Claude Code

## fix(deploy): give `migrate` the API's client-address settings, and say what Doctor checked **Cause of the production report.** Doctor said "Direct client-address mode" while the running `api` had `EKKLESIA_CLIENT_ADDRESS_MODE=trusted-proxy`. - Doctor checks the client-address configuration of **the process it runs in**. - Operators run it as `migrate`. - `compose.proxy.yaml` gave the three trusted-proxy variables to `api` only. Doctor therefore validated an empty configuration and reported direct mode for an installation that trusts its proxy. ### Commits 1. **Failing tests first.** On `main`: - `tests/deploy.test.ts`: `migrate` gets no client-address environment; - `core/tests/doctor.test.ts`: the check does not say whose configuration it read; - `scripts/smoke-deploy.sh`: Doctor through the proxy overlay must report `Trusted-proxy client-address mode`. Not run against `main` (Docker); it follows from the static test. 2. **The fix.** | Change | Why | |---|---| | `compose.proxy.yaml`: the variables are defined once as a YAML anchor and applied to `api` **and** `migrate` | Doctor checks what the API runs. Rendered with `docker compose config`: `api` is byte-for-byte unchanged, and `migrate` matches it, keeping `NODE_EXTRA_CA_CERTS` from the base | | `env/compose.env.example`: `COMPOSE_FILE=compose.yaml:compose.proxy.yaml` | The README's plain `docker compose run --rm migrate …` read `compose.yaml` alone, so even with the overlay fixed Doctor would not have seen it. This is what the instance's `deploy/.env` already does | | Doctor's client-address check, every outcome, gets one more detail line | It says it checked the environment Doctor runs with, and how to read the running API's own value: `docker compose exec api printenv EKKLESIA_CLIENT_ADDRESS_MODE` (confirmed to work in the image) | | `deploy/README.md` | Run operator commands with the same Compose files as the stack, and why it matters for Doctor | ### Verification - `pnpm verify`: passes. - `bash scripts/smoke-deploy.sh` (same-origin, Docker): passes, including `ok Doctor: READY, verify-full with the private CA, storage reachable, the API's client-address mode, no secret printed`. The five Biome warnings in `tests/deploy.test.ts` (`noTemplateCurlyInString` on Compose `${…}` strings) are pre-existing and unchanged. ### For the instance The instance vendors `deploy/` verbatim, and its `deploy/.env` already sets `COMPOSE_FILE` with the proxy overlay. After the platform pin bump and `scripts/vendor-deploy.sh`, its documented Doctor command reports trusted-proxy mode with no other change. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Zayin_Admin added 2 commits 2026-10-06 00:42:39 +00:00
Behind the reference proxy the API runs in trusted-proxy mode, but
compose.proxy.yaml gives those variables to `api` only. The documented
Doctor command runs as `migrate`, so it validated an empty
configuration and reported "Direct client-address mode" for an
installation that trusts its proxy. That is what the first production
installation saw.

Fails today:
- deploy.test.ts: the proxy overlay gives `migrate` no client-address
  environment;
- doctor.test.ts: the check does not say whose configuration it read;
- smoke-deploy.sh: Doctor through the proxy overlay does not report
  trusted-proxy mode (Docker).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
fix(deploy): give migrate the API's client-address settings, and say what Doctor checked
CI / verify (pull_request) Successful in 1m51s
CI / infrastructure-smoke (pull_request) Successful in 20s
CI / migration-smoke (pull_request) Successful in 1m48s
CI / image-build (pull_request) Successful in 35s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m16s
f1d6501239
Doctor checks the client-address configuration of the process it runs
in, and operators run it as `migrate`. The proxy overlay set
trusted-proxy mode on `api` only, so Doctor reported "Direct
client-address mode" for an installation that trusts its proxy.

- compose.proxy.yaml defines the three variables once, as a YAML
  anchor, and applies it to both `api` and `migrate`. Rendered with
  `docker compose config`, `api` is unchanged and `migrate` now
  matches it, keeping NODE_EXTRA_CA_CERTS from the base.
- The example deploy/.env sets
  COMPOSE_FILE=compose.yaml:compose.proxy.yaml, as the instance already
  does. Plain `docker compose run --rm migrate ...` in the README then
  runs with the overlay; it used to read compose.yaml alone.
- Every client-address check in Doctor now says it checked the
  environment Doctor runs with, and how to read the running API's own
  value (`docker compose exec api printenv
  EKKLESIA_CLIENT_ADDRESS_MODE`, confirmed to work in the image).
- The deploy README explains why operator commands need the same files
  as the stack.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Zayin_Admin force-pushed fix/doctor-client-address from 4a9012f64c to f1d6501239 2026-10-06 00:42:39 +00:00 Compare
Zayin_Admin merged commit dbb4648a35 into main 2026-10-06 01:18:19 +00:00
Zayin_Admin deleted branch fix/doctor-client-address 2026-10-06 01:18:19 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Zayin/Ekklesia#57