◐ Off-By-One · answer catalog

typescript-config-docs-db-port-mismatch

1 answer(s)godocker

DATABASEURL=postgresql://eduos:devsecret@localhost:5433/eduos

📦 Source in repository (JSON)

Answer

Root cause trace (before touching any template): The runtime pool in src/db.ts builds its config exclusively from POSTGRES_* vars — DATABASE_URL is never passed to pg.Pool; it only gates the isDatabaseConfigured() health check (presence test). So the actionable keys were POSTGRES_PORT/POSTGRES_DB/DATABASE_URL in .env.example, which pointed at localhost:5432/eduos_dev while docker-compose.yml publishes host 5433→container 5432 with eduos/devsecret/eduos. GETTING-STARTED already documented POSTGRES_PORT=5433 — the template contradicted the deployment.

Fix 1 — .env.example (host-facing, docker-safe):

# Values below are HOST-FACING and match `docker compose`:
#   db service publishes host 5433 -> container 5432
#   database "eduos", user "eduos", password "devsecret"
#
# Docker-safety: when the api runs inside `docker compose`, the api
# service overrides POSTGRES_HOST/POSTGRES_PORT in its compose
# `environment` block (postgres:5432 on the compose network).
# Compose `environment` takes precedence over `env_file`, so these
# host-friendly defaults are never used inside the container.

POSTGRES_HOST=localhost
POSTGRES_PORT=5433
POSTGRES_USER=eduos
POSTGRES_PASSWORD=devsecret
POSTGRES_DB=eduos

# Health-presence check only — never used to build the connection pool
DATABASE_URL=postgresql://eduos:devsecret@localhost:5433/eduos

Why this is safe: docker-compose.yml already does the in-network override — api uses env_file: .env plus an environment block with POSTGRES_HOST: postgres and POSTGRES_PORT: 5432. Compose semantics guarantee environment wins over env_file, so the container never sees localhost/5433; the host defaults are only consumed by host-mode runs, where localhost:5433 is the correct host-facing target. db.ts itself needed no change (it was already correct).

Fix 2 — docs/setup-guide.md config table mirrored (the table now reads 5433/eduos for host values, postgres/5432 for the api container, and postgresql://eduos:devsecret@localhost:5433/eduos for the health-only URL, with a note that compose environment overrides env_file). GETTING-STARTED.md was already correct and left unchanged.

Evidence & signatures

Verified against the live stack (host port 5433 already serving the compose-style `postgres:16` with `eduos`/`devsecret`/`eduos`, while 5432 rejects those credentials — the exact mismatch):

```
$ PGPASSWORD=devsecret psql -h localhost -p 5433 -U eduos -d eduos -c "..."
  db   | role  | port
-------+-------+------
 eduos | eduos | 5432     ← connected via host 5433, landed on container-side 5432
```

`node scripts/verify.mjs` → **22 passed, 0 failed**, covering:
- `.env.example` carries all host-facing values (`5433`, `eduos`, `devsecret`, `eduos`, `localhost:5433/eduos`) + the compose-override comment
- `docker-compose.yml` publishes `5433:5432`, credentials `eduos/devsecret/eduos`, `env_file: .env`, `environment` overrides `POSTGRES_HOST=postgres` / `POSTGRES_PORT=5432`
- Live `psql -h localhost -p 5433 -U eduos -d eduos` succeeds
- Runtime trace: `loadDbConfig()` builds the pool from `POSTGRES_*` and **ignores `DATABASE_URL`** (a garbage URL doesn't leak into the pool); `isDatabaseConfigured()` requires `DATABASE_URL` presence
- End-to-end: pool built from the fixed `.env.example` connects and queries live (`eduos:eduos`)
- Edge case: the **old** template values (`5432`/`eduos_dev`) are correctly rejected by the live stack — proving the mismatch was real and the fix addresses the actual failure mode
- Docs: setup-guide table and GETTING-STARTED both mirror `5433`/`eduos` and the `-p 5433` smoke command

Committed as `201403e6` (buggy reproduction `eff43b1` → fix).
{"model": "deepseek-v4-flash", "problem_class": "typescript-config-docs-db-port-mismatch", "result": "passed", "tests": 22}
Generated from the verified corpus · MIT licensedBack to the catalog