Replaces the per-setting environment: allow-list on the backend/worker/migrate services with env_file: .env, so every setting in app/core/config.py is configurable from .env with no compose edit — killing the recurring trap where a documented var (OWNER_EMAIL, AI keys, SMTP, APP_BASE_URL) silently never reached the app.
env_file is required: false, so local/CI without a .env still works (falls back to ${VAR:-default} + code defaults). Validated with docker compose config -q both with and without .env.
The remaining tiny environment: block pins only what must NOT come from .env: RUN_MIGRATIONS=1 (deploy flag) and DATABASE_URL (compose-internal host; code default is localhost). environment wins over env_file.
Trade-off (accepted):env_file also injects infra secrets (POSTGRES_*, MINIO_*, CLOUDFLARE_TUNNEL_TOKEN) into the app process env; the app ignores unknown vars.
Verified live on prod after recreate: DATABASE_URL→postgres:5432, RUN_MIGRATIONS=1 + OWNER_EMAIL intact, COOKIE_SECURE=true (checked beforehand — no security posture change), migrate exit 0, /health/ready 200, /api/v1/public/trees 200. Supersedes the explicit AI/SMTP/OWNER passthrough from #241/#242.
Replaces the per-setting `environment:` allow-list on the backend/worker/migrate services with `env_file: .env`, so **every** setting in `app/core/config.py` is configurable from `.env` with no compose edit — killing the recurring trap where a documented var (`OWNER_EMAIL`, AI keys, SMTP, `APP_BASE_URL`) silently never reached the app.
- `env_file` is `required: false`, so local/CI without a `.env` still works (falls back to `${VAR:-default}` + code defaults). Validated with `docker compose config -q` both with and without `.env`.
- The remaining tiny `environment:` block pins only what must NOT come from `.env`: `RUN_MIGRATIONS=1` (deploy flag) and `DATABASE_URL` (compose-internal host; code default is localhost). `environment` wins over `env_file`.
- **Trade-off (accepted):** `env_file` also injects infra secrets (`POSTGRES_*`, `MINIO_*`, `CLOUDFLARE_TUNNEL_TOKEN`) into the app process env; the app ignores unknown vars.
**Verified live on prod** after recreate: `DATABASE_URL`→`postgres:5432`, `RUN_MIGRATIONS=1` + `OWNER_EMAIL` intact, `COOKIE_SECURE=true` (checked beforehand — no security posture change), migrate exit 0, `/health/ready` 200, `/api/v1/public/trees` 200. Supersedes the explicit AI/SMTP/OWNER passthrough from #241/#242.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replace the per-setting environment allow-list with `env_file: .env` on the
three app-image services, so every setting in app/core/config.py is configurable
from .env with no compose edit. This kills the recurring trap where a documented
env var (OWNER_EMAIL, the AI keys, SMTP, APP_BASE_URL) silently didn't reach the
app because it wasn't on the hand-maintained list.
`env_file` is `required: false` so local/CI without a .env still works (falls
back to ${VAR:-default} interpolation + code defaults). The small `environment:`
block that remains is only for values that must NOT come from .env:
- RUN_MIGRATIONS=1 (backend) — a deploy flag, not an app setting.
- DATABASE_URL — pinned to the compose-internal host, because the code default
points at localhost (wrong inside the network). environment wins over
env_file, so this is a safety net if .env ever omits it.
Trade-off (accepted, see comment): env_file also injects infra secrets
(POSTGRES_*, MINIO_*, CLOUDFLARE_TUNNEL_TOKEN) into the app process env; the app
ignores unknown vars (pydantic extra="ignore").
Verified on prod: DATABASE_URL resolves to postgres:5432, RUN_MIGRATIONS=1 and
OWNER_EMAIL intact, COOKIE_SECURE=true (no posture change), health 200, trees
200. The earlier explicit AI/SMTP/OWNER passthrough is now subsumed by this.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Signed-off-by: Justin Paul <[email protected]>
justin
merged commit 0388b9b99f into main2026-06-10 08:46:16 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Replaces the per-setting
environment:allow-list on the backend/worker/migrate services withenv_file: .env, so every setting inapp/core/config.pyis configurable from.envwith no compose edit — killing the recurring trap where a documented var (OWNER_EMAIL, AI keys, SMTP,APP_BASE_URL) silently never reached the app.env_fileisrequired: false, so local/CI without a.envstill works (falls back to${VAR:-default}+ code defaults). Validated withdocker compose config -qboth with and without.env.environment:block pins only what must NOT come from.env:RUN_MIGRATIONS=1(deploy flag) andDATABASE_URL(compose-internal host; code default is localhost).environmentwins overenv_file.env_filealso injects infra secrets (POSTGRES_*,MINIO_*,CLOUDFLARE_TUNNEL_TOKEN) into the app process env; the app ignores unknown vars.Verified live on prod after recreate:
DATABASE_URL→postgres:5432,RUN_MIGRATIONS=1+OWNER_EMAILintact,COOKIE_SECURE=true(checked beforehand — no security posture change), migrate exit 0,/health/ready200,/api/v1/public/trees200. Supersedes the explicit AI/SMTP/OWNER passthrough from #241/#242.🤖 Generated with Claude Code
Replace the per-setting environment allow-list with `env_file: .env` on the three app-image services, so every setting in app/core/config.py is configurable from .env with no compose edit. This kills the recurring trap where a documented env var (OWNER_EMAIL, the AI keys, SMTP, APP_BASE_URL) silently didn't reach the app because it wasn't on the hand-maintained list. `env_file` is `required: false` so local/CI without a .env still works (falls back to ${VAR:-default} interpolation + code defaults). The small `environment:` block that remains is only for values that must NOT come from .env: - RUN_MIGRATIONS=1 (backend) — a deploy flag, not an app setting. - DATABASE_URL — pinned to the compose-internal host, because the code default points at localhost (wrong inside the network). environment wins over env_file, so this is a safety net if .env ever omits it. Trade-off (accepted, see comment): env_file also injects infra secrets (POSTGRES_*, MINIO_*, CLOUDFLARE_TUNNEL_TOKEN) into the app process env; the app ignores unknown vars (pydantic extra="ignore"). Verified on prod: DATABASE_URL resolves to postgres:5432, RUN_MIGRATIONS=1 and OWNER_EMAIL intact, COOKIE_SECURE=true (no posture change), health 200, trees 200. The earlier explicit AI/SMTP/OWNER passthrough is now subsumed by this. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Signed-off-by: Justin Paul <[email protected]>