Container Cannot Connect to Host Model: Minimal Reproduction & Diagnostic Steps
Solve the #1 self-hosted AI failure (`ECONNREFUSED` / `ETIMEDOUT` calling port 11434 from Open WebUI, n8n, or Dify) in three deterministic verification commands.
Verified on Ubuntu 24.04 (Docker Engine 27.x + UFW) & macOS 15 (Docker Desktop 4.36)
Includes firewall rules to keep port 11434 isolated from external LAN/WAN while opening it to local containers.
- Using `network_mode: host` fixes Linux networking instantly, but is NOT supported on Docker Desktop for macOS or Windows.
- Binding `OLLAMA_HOST=0.0.0.0` on a cloud VPS without a firewall immediately exposes your model server to internet scanners.
1. Minimal Reproduction of the Three Distinct Failure Modes
| Terminal Error Output | Failing Layer | Affected OS | Deterministic Fix |
|---|---|---|---|
| Connection refused (127.0.0.1:11434) | Container Namespace | All (Mac / Linux / Win) | Use http://host.docker.internal:11434 |
| Connection refused (172.17.0.1:11434) | Host Socket Bind | macOS & Linux systemd | Set OLLAMA_HOST=0.0.0.0:11434 on host |
| wget: bad address 'host.docker.internal' | Container /etc/hosts | Native Linux Docker Engine | Add extra_hosts: ["host.docker.internal:host-gateway"] |
| wget: download timed out (after 5s) | Host Firewall (UFW/iptables) | Ubuntu / Debian with UFW | ufw allow from 172.16.0.0/12 to any port 11434 |
docker run --rm --add-host=host.docker.internal:host-gateway alpine:3.20 \ sh -c "getent hosts host.docker.internal && wget -qO- --timeout=5 http://host.docker.internal:11434/api/version"
2. Security Boundary: Opening to Containers Without Exposing to the Internet
3. Multi-Container Compose Bridge vs Host Native Performance
Frequently Asked Questions & Edge Cases
Q: Why does `ufw allow from 172.17.0.0/16` still fail when I use `docker compose up`?
`172.17.0.0/16` only covers the default `docker0` bridge. Docker Compose automatically creates a new user-defined bridge network for each project using subnets like `172.18.0.0/16`, `172.19.0.0/16`, etc. Allowing the full private block `172.16.0.0/12` covers all Compose project bridges safely.
Q: After setting `launchctl setenv OLLAMA_HOST "0.0.0.0:11434"` on macOS, why is it still listening on `127.0.0.1`?
macOS GUI apps only read `launchctl` environment variables when launched. You must click the Ollama icon in the top menu bar -> **Quit Ollama**, and reopen it from `/Applications/Ollama.app` for the new socket bind to take effect.
Container-to-Host Local LLM Connectivity Diagnostic Script
Tests host bind address (127.0.0.1 vs 0.0.0.0), host.docker.internal DNS resolution, and bridge firewall rules.
#!/usr/bin/env bash # Tinker AI Troubleshooting — Container <-> Host Local Model Diagnostic (Guide #6) set -euo pipefail PORT="11434" CONTAINER="tinker-open-webui" echo "=== Step 1: Check Host Listening Address on Port $PORT ===" if lsof -nP -iTCP:"$PORT" -sTCP:LISTEN 2>/dev/null | grep -q "127.0.0.1:$PORT"; then echo "[FAIL] Host service is bound ONLY to 127.0.0.1:$PORT." echo " -> Fix: Set OLLAMA_HOST=0.0.0.0:$PORT on the host service and restart." else echo "[OK] Host service is not restricted to loopback only." fi echo "=== Step 2: Probe host.docker.internal from inside $CONTAINER ===" docker exec "$CONTAINER" sh -c "getent hosts host.docker.internal && wget -qO- --timeout=5 http://host.docker.internal:$PORT/api/version" \ && echo "[OK] Container reached host model API successfully!" \ || echo "[FAIL] Container cannot reach host.docker.internal:$PORT. Ensure extra_hosts: ['host.docker.internal:host-gateway'] is set."