TinkerLab
跳转可下载配置
04 // DIAGNOSISDocker 容器Apple Silicon MacNVIDIA 独显n8n 工作流阅读与复现约 8 分钟

容器连不上宿主机模型:最小复现和诊断步骤

用三条确定性终端命令,彻底解决 Open WebUI、n8n 或 Dify 容器访问宿主机 11434 端口报 Connection Refused 或 Timeout 的高频故障。

[核心实测结论 / TL;DR]在 Tinker AI 实测工坊针对「容器连不上宿主机模型:最小复现和诊断步骤」的复现测试中(实测环境:Ubuntu 24.04(Docker Engine 27.x + UFW 防火墙)与 macOS 15(Docker Desktop 4.36)双平台实测,软件版本:Docker Engine 27.x / Ollama 0.5.7 / Open WebUI v0.5.10 / n8n 1.76.x,验证日期:2026-10-23):用三条确定性终端命令,彻底解决 Open WebUI、n8n 或 Dify 容器访问宿主机 11434 端口报 Connection Refused 或 Timeout 的高频故障。 离线边界为「纯本机回环与容器网桥通信」(包含严格的网桥子网防火墙策略,在向本机容器放行 11434 的同时阻止外部网络访问。),关键限制包括:`network_mode: host` 虽然能在 Linux 下秒通,但在 macOS 和 Windows 的 Docker Desktop 下并不与宿主机共享网络栈(端口映射还会失效)。
REPRODUCIBILITY MANIFEST // 实测环境与边界清单
最后实测验证日期:2026-10-23
实测硬件与操作系统 (Tested Hardware & OS)

Ubuntu 24.04(Docker Engine 27.x + UFW 防火墙)与 macOS 15(Docker Desktop 4.36)双平台实测

锁定软件与模型版本 (Pinned Stack Versions)
Docker Engine 27.xOllama 0.5.7Open WebUI v0.5.10n8n 1.76.x
离线与外部连接核查 (Offline & Network Boundary)
纯本机回环与容器网桥通信

包含严格的网桥子网防火墙策略,在向本机容器放行 11434 的同时阻止外部网络访问。

已知限制与失败案例 (Known Limits)
  • `network_mode: host` 虽然能在 Linux 下秒通,但在 macOS 和 Windows 的 Docker Desktop 下并不与宿主机共享网络栈(端口映射还会失效)。
  • 在带有公网 IP 的云服务器上设置 `OLLAMA_HOST=0.0.0.0` 若不配防火墙,会导致 11434 端口直接暴露给全网扫描器。
遇到环境异常?打开排障诊断树 →

1. 三种不同报错背后的最小复现与根因对照

“连不上”在网络层其实分为三种截然不同的故障模式,可通过一行最小复现命令立即区分: • **秒报 `Connection refused`**:容器内误填了 `localhost:11434`,或者宿主机 Ollama 仍绑定在默认的 `127.0.0.1:11434`。 • **秒报 `bad address 'host.docker.internal'`**:运行在原生 Linux Docker 下,未声明 `extra_hosts: ["host.docker.internal:host-gateway"]`。 • **卡住数秒后报 `Operation timed out`**:监听地址与域名解析均正常,但宿主机 `ufw` / `iptables` 防火墙丢弃了来自 `docker0` 网桥(`172.16.0.0/12`)的数据包。
表 1:容器访问宿主机 11434 端口的报错特征与跨平台修复矩阵
终端报错信息故障层级高发系统环境确定性修复动作
Connection refused (指向 127.0.0.1)容器网络命名空间全平台通用将地址改为 http://host.docker.internal:11434
Connection refused (指向网桥 IP)宿主机监听网卡限制macOS 与 Linux 原生安装宿主机设置 OLLAMA_HOST=0.0.0.0:11434
bad address 'host.docker.internal'容器内 DNS / hosts 缺失原生 Linux Docker 环境Compose 添加 host-gateway 映射
timed out(卡住 5 秒后超时)宿主机防火墙拦截网桥开启了 UFW 的 Ubuntu/Debian仅对 172.16.0.0/12 放行 11434
One-Line Minimal Reproduction Probe
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. 安全边界:向本机容器放行但严禁暴露公网

在 Linux 服务器上设置 `OLLAMA_HOST=0.0.0.0:11434` 后,除了容器网桥可以访问外,物理网卡也会同步暴露该端口。切记配合 UFW 规则仅允许 `172.16.0.0/12` 容器网段入站,或直接将 `OLLAMA_HOST` 绑定在 `docker0` 虚拟网卡 IP(`172.17.0.1:11434`)上。

3. 同栈自定义 Bridge 网桥与宿主机原生运行的选型权衡

在配备 NVIDIA 独显的 Linux 机器上,你也可以将 Ollama 与 Open WebUI / n8n 放在同一个 `docker-compose.yml` 自定义网桥下,直接通过服务名 `http://ollama:11434` 内部通信,完全避开宿主机防火墙配置。但在 Apple Silicon Mac 上,由于 Docker 虚拟机无法使用 Metal GPU,Ollama **必须**原生跑在 macOS 宿主机上,此时必须走 `host.docker.internal:11434`。
FIELD Q&A // 常见实测疑问与边界解答

复现常见疑问与深层原理解答

Q: 为什么我已经放行了 `172.17.0.0/16`,但用 `docker compose up` 启动的容器还是连不上宿主机?

`172.17.0.0/16` 仅代表默认的 `docker0` 网桥;而 `docker compose` 会为每个项目创建独立的自定义网桥(通常分配在 `172.18.x.x`、`172.19.x.x` 等子网)。因此防火墙规则应放行整个 `172.16.0.0/12` 私有网段。

Q: 在 macOS 上执行了 `launchctl setenv OLLAMA_HOST "0.0.0.0:11434"` 后,为什么 `lsof` 还是显示 `127.0.0.1`?

macOS 桌面应用仅在进程启动时读取 `launchctl` 环境变量。执行命令后,必须在顶部菜单栏点击 Ollama 图标选择 **Quit Ollama** 彻底退出,再重新打开应用才能生效。

REPRODUCIBLE ARTIFACT // 配套可参数化附件

容器连不上宿主机本地模型:最小复现与跨平台诊断脚本

自动排查宿主机 127.0.0.1 监听限制、容器内 host.docker.internal 解析与 Linux 网桥防火墙拦截。

diagnose-container-llm.sh ↗
修改上方参数将实时更新下方配置内容
#!/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."

更多可复现工程指南

查看全部 42 篇指南 →