compose: drive app config from .env (env_file, blanket passthrough) #243
Reference in New Issue
Block a user
Delete Branch "compose-env-file"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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) <noreply@anthropic.com> Signed-off-by: Justin Paul <justin@jpaul.me>