Skip to content

Commit ea672a4

Browse files
author
J.A.R.V.I.S
committed
fix(docker): HTTP server must bind 0.0.0.0 in container for port mapping to work
Root cause of smoke test failure: ThreadingHTTPServer was bound to '127.0.0.1' inside the container. Docker port mapping (-p 8100:8100) only forwards to 0.0.0.0 listeners; a 127.0.0.1-only bind is not reachable from the host even with the port mapping configured. Changes: - acp_relay.py: add --http-host flag (default: 127.0.0.1 for backward compat) and pass it through to run_http() - Dockerfile CMD: add --http-host 0.0.0.0 so the container exposes HTTP correctly via Docker port mapping
1 parent cb59790 commit ea672a4

2 files changed

Lines changed: 13 additions & 6 deletions

File tree

Dockerfile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
6868
CMD python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:8100/.well-known/acp.json', timeout=4)" || exit 1
6969

7070
# Default: listen on all interfaces inside the container
71-
# Pass any acp_relay.py flags after the image name
71+
# --http-host 0.0.0.0 is required so Docker port mapping (-p 8100:8100) works;
72+
# the HTTP server must bind 0.0.0.0 inside the container, not 127.0.0.1.
73+
# Pass any acp_relay.py flags after the image name to override defaults.
7274
ENTRYPOINT ["python3", "/app/acp_relay.py"]
73-
CMD ["--name", "ACP-Agent", "--port", "8000"]
75+
CMD ["--name", "ACP-Agent", "--port", "8000", "--http-host", "0.0.0.0"]

relay/acp_relay.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,12 +2225,13 @@ def do_PATCH(self):
22252225
self._json({"ok": True, "availability": live_card.get("availability", {})})
22262226

22272227

2228-
def run_http(port):
2228+
def run_http(port, host="127.0.0.1"):
22292229
# BUG-001 root-cause fix (2026-03-23): use ThreadingHTTPServer so that
22302230
# /stream (blocking SSE loop) does not prevent /message:send from being served.
22312231
# The original HTTPServer was single-threaded; any open /stream connection
22322232
# would block ALL subsequent HTTP requests, making SSE effectively useless.
2233-
ThreadingHTTPServer(("127.0.0.1", port), LocalHTTP).serve_forever()
2233+
# host defaults to 127.0.0.1 (local-only); pass "0.0.0.0" for Docker/container use.
2234+
ThreadingHTTPServer((host, port), LocalHTTP).serve_forever()
22342235

22352236

22362237
# ══════════════════════════════════════════════════════════════════════════════
@@ -2441,6 +2442,9 @@ def main():
24412442
"Format: URI or URI,required=true,param_key=param_val. "
24422443
"Example: --extension https://acp.dev/ext/availability/v1,required=false "
24432444
" --extension https://corp.example.com/ext/billing,tier=pro")
2445+
parser.add_argument("--http-host", default="127.0.0.1", metavar="HOST",
2446+
help="Host/IP the HTTP interface binds to (default: 127.0.0.1). "
2447+
"Use 0.0.0.0 for Docker/container deployments so port mapping works.")
24442448

24452449
args = parser.parse_args()
24462450

@@ -2571,8 +2575,9 @@ def _get_bool(cli_flag: bool, cfg_key: str) -> bool:
25712575
_inbox_path = args.inbox or f"/tmp/acp_inbox_{args.name.replace(' ', '_')}.jsonl"
25722576
log.info(f"Message persistence: {_inbox_path}")
25732577

2574-
threading.Thread(target=run_http, args=(http_port,), daemon=True).start()
2575-
log.info(f"HTTP interface: http://127.0.0.1:{http_port}")
2578+
http_host = getattr(args, "http_host", "127.0.0.1")
2579+
threading.Thread(target=run_http, args=(http_port, http_host), daemon=True).start()
2580+
log.info(f"HTTP interface: http://{http_host}:{http_port}")
25762581

25772582
# ── mDNS LAN discovery (v0.7) ─────────────────────────────────────────────
25782583
if args.advertise_mdns:

0 commit comments

Comments
 (0)