agent-proxy: container binds PROXY_PORT=8082 but compose maps to container :8080 - proxy never serves on 127.0.0.1:8082 #430
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/infrastructure#430
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Problem
The
agent-proxyrole converges the container but it does not serve on127.0.0.1:8082- the validation curls indocs/agent-proxy.md(/v1/healthz,/v1/models) fail with a connection reset even thoughdocker psshows the container up.Root cause -
PROXY_PORTis overloadedThe agent-proxy server binds to
settings.proxy_port(coilyco-flight-deck/agent-proxyapp/__init__.py:59,app/config.py:54), fed by thePROXY_PORTenv var, default8080. The DockerfileEXPOSEs8080and the compose mapping hardcodes the container side to8080.But
ansible/roles/agent-proxy/tasks/main.ymlpassesPROXY_PORT: "{{ agent_proxy_port }}"(=8082, the default) into the container environment. So:0.0.0.0:8082files/compose.yamlmaps127.0.0.1:${PROXY_PORT:-8082}:8080-> host8082to container80808080, so host8082accept-then-resetsPROXY_PORTis doing two jobs at once - the host publish port and the container's internal listen port - and only the host side received8082.Fix
Separate the two. The container should always listen on a fixed internal
8080(matching the DockerfileEXPOSEand the app default) and only the published host port should vary withagent_proxy_port. Concretely, in this repo (no agent-proxy repo change needed):files/compose.yaml: publish127.0.0.1:${AGENT_PROXY_PUBLISH_PORT:-8082}:8080and pin the container envPROXY_PORT: "8080"(leavePROXY_HOSTas-is at0.0.0.0so Docker forwarding can reach it).tasks/main.yml: stop pushingagent_proxy_portinto the container'sPROXY_PORT; pass it as the publish-port var instead. KeepPROXY_HOST: 0.0.0.0andPROXY_TOWER_BASE_URLunchanged.Pick whatever var names read cleanly - the invariant is: published host port =
agent_proxy_port, container internal port = fixed 8080, and the two ends of the mapping agree with where the app actually binds.Acceptance
ward exec ansible-syncon a mac,curl -fsS http://127.0.0.1:8082/v1/healthzand/v1/modelssucceed (tower reachable).docker logs agent-proxyshows the app binding the same container port the mapping targets.agent_proxy_portstill works end to end (publish port changes, container stays on 8080).Refs
08f117f(closes #425).docs/agent-proxy.mdvalidation steps are the reproduction.🔒 Reserved by
ward agent --driver claude— containerengineer-claude-infrastructure-430on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-02T07:55:43Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - compose publishes AGENT_PROXY_PUBLISH_PORT->:8080, container PROXY_PORT pinned to 8080, tasks/main.yml passes agent_proxy_port as the publish var
This one was a clean, well-scoped fix - the issue body basically wrote the diff, and the root cause (PROXY_PORT wearing two hats) was exactly as described. The actual code change was three lines across two files.
What fought back wasn't the fix, it was the toolchain: the
code-commentshook rejects any YAML comment below the top header block, so my inline "why" comments had to move up into the file header. And thepylintpre-commit hook couldn't run because the container'sUV_PYTHON_INSTALL_DIR(/opt/uv/python) is read-only and the project needs Python 3.13 - I redirected uv's install dir to$HOME/.uv-pythonso the hook could download and pass (10.00/10). Worth flagging as a container-env rough edge if other runs hit the same wall.Confidence is high on the mapping being correct-by-construction (both ends now agree on :8080, publish port varies), but I could not run the live acceptance curls - no mac / running container / tower reachable from here, and the SSM api-token wasn't available to check Forgejo CI. So the end-to-end
/v1/healthz+/v1/modelsverification still wants a realward exec ansible-syncon a mac to close out. No follow-ups needed beyond that manual confirmation.Correcting the diagnosis on this one. The observed local failure is not the port mapping -
docker logs agent-proxyshows the container crash-looping onModuleNotFoundError: No module named 'pydantic_settings', so it never binds any port at all. That root cause is a malformed dependency declaration in the agent-proxy image, tracked in coilyco-flight-deck/agent-proxy#22.This port-mapping bug is still real, but it is latent - it only surfaces once the container actually boots. With
agent_proxy_port: 8082pushed into the container asPROXY_PORT, the app binds0.0.0.0:8082whilecompose.yamlmaps host8082-> container8080, so/v1/healthzwould still fail even on a healthy image. Keep this fix (pin the container's internal port to 8080, vary only the published host port).Ordering for a green end-to-end: agent-proxy#22 (deps) unblocks boot, this (#430) fixes the healthcheck path, and infrastructure#431 makes the role actually rebuild the image so the fixed upstream reaches the host. Same role/file as #431 - whichever lands second integrates the first.