Skip to content

Fix prod compose ports override silently not applying - #476

Merged
WilfordGrimley merged 2 commits into
masterfrom
prod-ports-override
Jul 25, 2026
Merged

Fix prod compose ports override silently not applying#476
WilfordGrimley merged 2 commits into
masterfrom
prod-ports-override

Conversation

@WilfordGrimley

@WilfordGrimley WilfordGrimley commented Jul 25, 2026

Copy link
Copy Markdown

Closes #475

Problem

docker-compose.prod.yml's postgres/elasticsearch services extends the base docker-compose.yml's services rather than defining their own. A plain ports: [] override does NOT reset a list field inherited through extends — Compose only replaces a list on a literal (non-extended) service override. Result: the base file's 127.0.0.1:5432/127.0.0.1:9200 host-port mapping was silently surviving into prod, confirmed live via ss -tln, despite docs/infrastructure.md asserting the override worked.

Severity (per the issue): moderated by the base mapping binding 127.0.0.1 only — nothing internet-exposed — but the documented hardening was silently not in effect, and local-process DB/ES access with the compose-file credentials was live.

Fix chosen: option (b) — Compose !reset merge tag

Considered option (a) (drop ports: from the base file, add it explicitly wherever the dev workflow invokes compose) but the dev workflow (per docker-compose.yml's own header comment — "spins up the database services required by the MPC Autofill backend... to enable local development through a Python virtual environment running natively on the dev machine") runs the base file directly, and no docker-compose.dev.yml-style override already exists in this repo. Per the constraint on this build ("add a dev override file ONLY if one already exists"), creating one wasn't an option, so option (a) was not available — went with option (b) instead.

Tagged both postgres and elasticsearch's ports: [] in docker-compose.prod.yml with the Compose merge tag !reset (ports: !reset [], Compose spec v2.24+), which forces an actual reset instead of a no-op override through extends. Verified supported by this box's CLI (docker compose version → v5.3.1).

docs/infrastructure.md's Postgres/ES ports note updated in place to describe the real (previously wrong) mechanism and the fix.

Verification

  • Dev path (docker compose -f docker-compose.yml config, base file untouched): postgres/ES both still render their 127.0.0.1:5432/127.0.0.1:9200 ports: mapping — dev behavior unchanged.
  • Prod path (docker compose -f docker-compose.prod.yml config, with dummy env vars for interpolation): postgres/ES both render ports: null (i.e., no host-port mapping) while expose: ["5432"]/["9200"] (container-to-container) stays populated. Confirms !reset actually works against this CLI version. Re-rendered after the expose: typo fix below — confirmed ports: null unchanged for both services, only elasticsearch's expose: value moved from 5432 to 9200; nothing else shifted.
  • docs_lint.py clean.
  • Pre-commit: the plain check-yaml hook doesn't know the Compose-specific !reset tag ("could not determine a constructor for the tag '!reset'") — scoped a second check-yaml instance with --unsafe (syntax-only, not "skip the file" — still catches real YAML syntax errors) to just docker-compose.prod.yml in .pre-commit-config.yaml, excluded that one file from the default strict instance. All hooks pass.

Rider note (per issue #475)

The live listener does not disappear until the postgres/ES containers are next recreated — Docker doesn't retroactively apply a compose-file port change to an already-running container. This rides on #462's (client_connection_check_interval) already-scheduled deliberate postgres recreate — if the two land together, one recreate covers both fixes. Until that recreate happens, 127.0.0.1:5432/127.0.0.1:9200 remain live on this box exactly as before.

Follow-up commit (same PR)

elasticsearch's expose: in docker-compose.prod.yml was - 5432 (should be 9200) — pre-existing on master, not introduced by this PR's first commit, but fixed here in an additive commit to keep this PR's "prod compose port hygiene" story complete since it's the same file this PR already owns. expose: doesn't gate traffic the way ports: does (informational only, container-to-container), so this was cosmetic rather than a live-traffic bug, but it was pointing at the wrong port.

Checklist

  • !reset verified against this box's Compose CLI (v5.3.1)
  • docker compose -f docker-compose.prod.yml config shows ports: null for postgres and elasticsearch
  • docker compose -f docker-compose.yml config (dev) unchanged, still publishes both ports
  • docs/infrastructure.md ports note updated to match verified reality
  • Rider note: live listener persists until the next postgres/ES recreate
  • Deviation (creating check-yaml --unsafe scoping) documented above
  • elasticsearch expose: typo (5432 -> 9200) fixed in a follow-up commit; re-rendered docker compose -f docker-compose.prod.yml config confirms ports: null unchanged for both services

ports: [] doesn't reset a list inherited via extends; tag it !reset so
postgres/ES actually stop publishing host ports in prod. Scopes
check-yaml's --unsafe to just this file for the custom Compose tag.
@WilfordGrimley
WilfordGrimley merged commit b654544 into master Jul 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prod compose ports:[] override silently ineffective: postgres/ES bound to localhost host ports

1 participant