Connection refused跟model not found是两码事。前者连 11434 端口都没建立;后者连上了但本地没这个模型。先curl一次/api/version,能把问题二分到「服务没起」或「网络绑定/容器边界」一侧。
Issue & Env(案发现场与环境)
- 业务场景:本地装好 Ollama 准备跑 DeepSeek-R1,命令行
curl http://localhost:11434直接报连接被拒;有时是同机能通、其它机器或容器里就连不上。 - 环境:Ollama v0.34.x(与 v0.30+ 行为一致),本地默认端口 11434;macOS 桌面 app、Linux systemd 托管、Docker 容器三种部署都有各自的踩坑点。
StackTrace(堆栈日志)
最常见的两种客户端报错,原样保留:
curl: (7) Failed to connect to 127.0.0.1 port 11434: Connection refused
Ollama CLI 自己抛的:
Error: could not connect to ollama app, is it running?
注意 Connection refused 是 TCP 层立刻被内核拒掉,请求根本没到 Ollama 进程;返回时间几乎是 0。如果连接挂了一会儿才挂,多半是 Connection timed out,不是 refused,二者排错方向不同。
Reproduce(复现代码)
干净装一遍后最容易复现的场景:
# 1) 安装脚本跑完,没起服务就 curl
curl http://localhost:11434/api/version
# 期望返回 {"version":"0.34.x"};实际:Connection refused
# 2) Ollama 在跑,但客户端跑在 Docker 容器里
docker run --rm alpine sh -c "apk add curl && curl http://localhost:11434/api/version"
# 期望:Connection refused(容器里的 localhost 指容器自己)
# 3) Linux 上 systemd 单元存在但没启动
sudo systemctl status ollama
# Active: inactive (dead) → curl 同样 Connection refused
Root Cause(根因分析)
Connection refused 在 Ollama 上收敛到三类原因。
一、服务进程没起来
Linux 装好后是 systemd 单元:sudo systemctl status ollama 看 Active 行是不是 active (running)。macOS 上 Ollama 是常驻 app,菜单栏图标消失 = 服务停止。Windows 上从托盘启动,关掉托盘就是关掉服务。装完没启动就直接 curl,必然 refused。
二、OLLAMA_HOST 默认只绑 127.0.0.1
这是官方 FAQ 直接给的策略:Ollama binds 127.0.0.1 port 11434 by default. Change the bind address with the OLLAMA_HOST environment variable. 也就是说同机能通,换个接口(另一个网卡、容器、远程)就被拒。这是设计不是 bug。
注意 OLLAMA_HOST 是双重身份:服务端拿它决定 bind 地址,客户端拿它决定 dial 地址。同一台机器的 systemd 单元把它配成 0.0.0.0:11434 后,ollama CLI 在本机走 127.0.0.1 还是通的;但如果把单元改成某个具体 LAN IP,本机 127.0.0.1 也会被拒。
三、容器里的 localhost 指容器自己
跑在 Docker 容器里的应用访问 localhost:11434,命中的是容器自己的 loopback,不是宿主机的 Ollama。Docker Desktop(macOS/Windows)提供 host.docker.internal 这个特殊域名;Linux Docker 20.10+ 也支持,否则要 --network host 或 --add-host=host.docker.internal:host-gateway。
另外 macOS 桌面 app 不继承 shell 的环境变量,把 OLLAMA_HOST 写在 ~/.zshrc 里对运行中的 app 没用——官方 FAQ 给的是 launchctl setenv OLLAMA_HOST "0.0.0.0:11434",然后完全退出并重启 app。在 app 没退干净的情况下改环境变量,听起来改了,实际进程没读到。
四、systemd 单元的覆盖关系
Linux 上 Ollama 的主单元文件是 vendor 自带的(/etc/systemd/system/ollama.service 或 /lib/systemd/system/ollama.service),直接编辑主文件会在下次 ollama 包升级时被覆盖。systemctl edit ollama 走的是 ollama.service.d/override.conf drop-in 机制,不会被升级覆盖。每次改完都要 daemon-reload + restart,缺一不可——单 restart 不重读新环境变量的情况常见。
验证生效:
systemctl show ollama -p Environment
# Environment=OLLAMA_HOST=0.0.0.0:11434 PATH=/usr/local/sbin:...
如果输出里没有 OLLAMA_HOST,说明 drop-in 没生效,回头检查 [Service] 拼写和重启步骤。
The Fix(解决方案)
第一步:二分问题
curl http://127.0.0.1:11434/api/version
- 返回
{"version":"0.34.4"}:服务活,问题在网络层或容器边界。跳第三步。 - Connection refused:服务没起。走第二步。
第二步:起服务
macOS:从 Applications 里启动 Ollama,菜单栏出现图标即可。
Linux:让 systemd 接管。
sudo systemctl status ollama
sudo systemctl start ollama
sudo systemctl enable ollama # 开机自启
journalctl -u ollama -n 100 --no-pager # 起不来就翻日志
临时调试可以前台跑,把日志看在屏幕上:
ollama serve
第三步:需要外部访问时改 OLLAMA_HOST
systemd 走 drop-in,不要直接改单元文件:
sudo systemctl edit ollama
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
sudo systemctl daemon-reload
sudo systemctl restart ollama
ss -tlnp | grep 11434 # 应该看到 0.0.0.0:11434
0.0.0.0 等于把 11434 暴露到所有网络接口。Ollama 自己不带鉴权,咖啡店 Wi-Fi 上这么做就等于把模型列表和推理能力送给同网段的人。要么绑具体 LAN IP,要么前面加 nginx 代理 + 防火墙。
第四步:容器内连宿主机
Docker Desktop:
services:
app:
environment:
OLLAMA_BASE_URL: http://host.docker.internal:11434
Linux Docker:
docker run --network host your-app
# 或
docker run --add-host=host.docker.internal:host-gateway your-app
容器里跑 Ollama 时则反过来——除了 -p 11434:11434,还得在容器内把 OLLAMA_HOST=0.0.0.0,否则容器里的 Ollama 还是绑 127.0.0.1,对外不可达。
docker run -d --name ollama -p 11434:11434 \
-e OLLAMA_HOST=0.0.0.0 \
-v ollama:/root/.ollama \
ollama/ollama
改完后再 curl 一次,确认是 Ollama is running 而不是 refused。
References(参考来源)
- Ollama FAQ — Ollama 官方文档ollama-docs
- Ollama Connection Refused on Port 11434: 8 Causestroubleshooting-guide
- Fix common Ollama errors: 500, timeouts and stalled pullstroubleshooting-guide
