在 N1 这种小盒子上装好飞牛 NAS、跑起 Ollama 之后,最容易踩的一步是把 11434 端口直接甩给局域网:手机、电脑、各类 Agent 客户端各配一个地址,模型改名要挨个通知,有人跑爆一次内存没人提前知道,更别提密钥与配额。
常规做法要么给每台设备写死 http://NAS:11434,要么在路由器上做端口映射再手工记账。前者没有鉴权、没有限额,出问题只能靠猜;后者把内网服务往外推,等于给自己挖坑。缺的其实是一个站在 Ollama 前面的接口层------它得会发 Token、会限模型、会记用量,还得在低功耗 ARM 盒子上跑得动。
本文分享一套在飞牛 NAS 上可直接落地的方案:New-API 做中转网关 + 本地 Ollama 当模型引擎 + 每台设备一把 Token,从容器编排到分发调用一次讲清。
一、为什么不让设备直连 Ollama:裸端口的三笔账
先算清直连的代价,再决定要不要加网关,直连方案欠着三笔账:
- 没有鉴权:任何能连上 11434 的机器都能调用,笔记本外借一次,等于把整台 NAS 的算力公开。
- 没有模型白名单 :
qwen2.5:7b、deepseek-r1:8b全量可见可调,一个 Agent 误拉大模型就能把内存吃干。 - 没有用量记录:Token 花在谁身上、哪个应用最烧钱,事后只能翻 Ollama 日志瞎猜。
把两种形态放一起看,差距一目了然:
| 维度 | 直连 Ollama | New-API 中转 |
|---|---|---|
| 访问控制 | 无,靠端口隐蔽 | Token 鉴权,可绑 IP |
| 模型可见性 | 全量暴露 | 按 Token 勾选白名单 |
| 用量统计 | 无 | 按 Token 与模型计费 |
| 协议 | 仅 Ollama 原生 | OpenAI 兼容,客户端通吃 |
| 对外端口 | 11434 需自管 | 只开一个网关端口 |
核心结论: Ollama 只当引擎,门面交给网关,改动只做一次,收益是长期的。

二、把两个容器拉起来:一份 compose 定下内网边界
这份 compose 适配飞牛 NAS 自带的 Docker,一次定义两个容器与一条内部网络:
yaml
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
volumes:
- ./ollama:/root/.ollama # 模型权重持久化
networks: [ai-net] # 不发布端口,仅内网可达
new-api:
image: calciumion/new-api:latest
container_name: new-api
restart: unless-stopped
ports:
- "3000:3000" # 唯一对外入口
volumes:
- ./data:/data # SQLite 与配置持久化
depends_on: [ollama]
networks: [ai-net]
networks:
ai-net:
driver: bridge
要点:Ollama 不发布端口、只挂内部网络,对外收敛到 New-API 的 3000 一个口。
还有两条细节值得留意:
- 模型目录持久化 :
./ollama映射权重,重建容器不用重下模型。 - 数据库默认 SQLite:个人规模够用,将来上 MySQL 只需补一个环境变量。
docker compose up -d → 两个容器同网互通 → 外界只见 3000
三、把 Ollama 挂进 New-API:渠道就是一条内网地址
New-API 里"渠道"决定模型从哪来,指向 compose 内的服务名即可:
- 渠道类型选 Ollama:网关原生支持该类型,会把本地模型翻译成 OpenAI 兼容接口。
- 代理地址填
http://ollama:11434:填 compose 网络里的服务名,不是 NAS 的局域网 IP。 - 模型名手工补齐 :该渠道不自动同步列表,需要把
ollama list的结果填进去。
下面两条命令分别在宿主机与网关容器内执行,用来拉模型和验证上游连通:
bash
# 宿主机:拉一个 7B 模型,8G 内存或显存即可承载
docker exec ollama ollama pull qwen2.5:7b
# 网关容器内:验证服务名解析与上游端口是否正常
docker exec new-api curl -s http://ollama:11434/api/tags | head -c 300
上游连通 → 模型上架 → 之后的管控全部收在网关侧完成。

四、发 Token:给每台设备一把专属钥匙
网关通了之后分发全靠 Token,一个 Token 就是一条最小权限策略:
- 先建 Token 再发出去:Token 是网关里唯一对外的身份凭证,设备本身不留任何密钥。
- 模型白名单优先:只勾设备真正要用的模型,避免大模型被无关客户端误调。
Token 的四个关键配置建议这样给:
| 配置项 | 建议值 | 作用 |
|---|---|---|
| 可用模型 | 勾选 1~2 个 | 白名单,其余模型一律拒绝 |
| 额度 | 按设备估算 | 超额自动停用,防止跑飞 |
| 过期时间 | 90 天 | 到期轮换,避免长期凭证 |
| IP 限制 | 按需开启 | 固定出口的办公网设备适用 |
客户端统一走 OpenAI 兼容接口,下面这条命令在任意终端都能跑:
bash
curl http://NAS_IP:3000/v1/chat/completions \
-H "Authorization: Bearer sk-你的令牌" \
-H "Content-Type: application/json" \
-d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"一句话总结飞牛NAS"}]}'
设备申请 → 后台建 Token → 勾模型限额度 → 客户端粘贴地址与 Token
客户端只认 OpenAI 格式,后端换模型、换机器,应用侧零改动。
五、跑通之后的排错:四个高频报错对齐表
首次跑通后最常见的四个坑,按现象直接对号入座:
| 现象 | 原因 | 处理 |
|---|---|---|
| 渠道测试 connection refused | 地址填了 NAS IP 而非服务名 | 改回 http://ollama:11434 |
| 模型列表为空 | Ollama 渠道不自动同步 | 在渠道里手工补模型名 |
| 调用返回 401 | Token 过期或被停用 | 重置额度或新建 Token |
| 首 token 等很久 | 模型未加载进内存 | 先预热一次或换小模型 |
排查时按这个顺序走最省时间:
- 先看容器日志 :
docker logs new-api与docker logs ollama顺着看,网关报错基本能追到上游。 - 再验内网连通:在网关容器里 curl 一次上游,比在宿主机上测更能说明问题。
排错顺序:容器日志 → 内网连通 → Token 状态 → 模型加载,八成问题在前两步就收敛了。
六、让它长期可用:巡检脚本与配置备份
NAS 上的服务不怕跑不通,怕的是悄悄跑不动,两条措施就够兜底:
- 定时健康检查:每小时请求一次网关接口,异常即记录并把通知推到手机。
- 配置与模型备份 :compose 文件、
./data目录与 Token 清单定期导出,换盘重装十分钟恢复。
下面这段脚本用宿主机自带的 python3 就能跑,适合挂进 cron 或飞牛的任务计划:
python
import json, time, urllib.request
URL = "http://127.0.0.1:3000/v1/models" # 只探网关自身
for _ in range(3): # 连续失败三次才报警
try:
with urllib.request.urlopen(URL, timeout=5) as r:
print(time.strftime("%F %T"), "OK", len(json.load(r)["data"]))
break
except Exception as e:
print(time.strftime("%F %T"), "FAIL", e)
time.sleep(5)
健康检查只看网关、不看模型:网关活着,模型的死活交给渠道测试兜底。
巡检发现异常 → 查网关日志 → 重启渠道或换模型 → 恢复后补一次备份

结语
这套东西跑起来之后,飞牛 NAS 就不再是"只存文件的盒子",而是一层随时可用的 AI 能力出口。N1 这类低功耗硬件跑 7B 模型本就吃紧,New-API 这层网关几乎不额外占用资源,却补齐了鉴权、白名单、限额与日志四件事;客户端侧凡是认 OpenAI 协议的应用都能直接接入,零改造。
往后无论是给手机上的 AI 应用发一个 Token,还是给自动化 Agent 单独建一条受限凭证,都只在网关后台点几下,不必再动 NAS 上的任何容器。
模型在内网里当引擎,Token 在门面上当闸门------这才是本地 AI 服务该有的样子。