1. 为什么要在 Docker 里同时跑 Ollama 和统一 API 网关如果你正在自建 AI 服务大概率会遇到这样一个局面本地用 Ollama 跑着 qwen2、llama3、glm4 几个模型云端又开了好几家的 API每个平台的 Key 格式不一样接口路径不一样模型名还各叫各的。写业务代码的时候光是一个调用大模型的动作就要维护三四套 SDK 和鉴权逻辑改一个模型名得翻半天文档。这个问题的本质是密钥分散 接口不统一。Ollama 本身只提供/api/chat、/api/generate这类原生接口而 OpenAI 生态里大家习惯的是/v1/chat/completions。你本地跑一个模型云端调一个模型前端代码就得写两套分支。更麻烦的是Ollama 默认没有鉴权端口一暴露谁都能调你的模型。我试过的解法是用 Docker Compose 把 Ollama 和 One-API 兼容层放在同一个网络里Ollama 只在内网暴露对外统一走 One-API 的 OpenAI 兼容接口。然后在这个兼容层之上再接一层 TaoToken 的统一 Key 通道把本地模型和云端模型都收敛到同一个 Base URL、同一个 Key、同一套模型 ID 命名规范下。这样业务侧只需要认一个地址换模型就是改一个字符串。这套方案适合谁适合已经在用 Docker 管理服务、手上有几台机器、想把手头零散的模型调用统一起来的开发者。你不需要有 GPU纯 CPU 也能跑 7B 级别的模型只是速度慢一点。下面我把整个部署过程拆成可以直接复制的步骤包括 docker-compose 配置、环境变量模板、curl 验证命令以及我自己踩过的几个报错。2. TaoToken 统一 Key 通道的前置准备在动手写 compose 文件之前先把统一通道这一层想清楚。TaoToken 在这里扮演的角色是一个 OpenAI 兼容的聚合入口它对外提供标准的/v1/chat/completions、/v1/models接口你拿一个 Key 就能调用它背后挂载的多个模型。对于本地 Ollama 来说我们通过 One-API 兼容层把 Ollama 的原生接口转成 OpenAI 格式再把这个兼容层作为一个上游注册进去对于云端模型直接在 TaoToken 侧配置即可。最终业务代码只认 TaoToken 的 Base URL。你需要先拿到两样东西一个是 TaoToken 的 API Key一个是确认好要用的模型 ID。Key 的获取入口在控制台的 API Keys 页面地址是https://taotoken.net/console/api-keys登录后新建一个 Key复制出来保存好后面环境变量里要用。模型 ID 可以先不急着定等 Ollama 把模型拉下来、One-API 注册完渠道之后再统一在 TaoToken 侧做映射。这里有个概念要区分清楚One-API 兼容层是跑在你本地的它负责把 Ollama 的原生接口翻译成 OpenAI 格式TaoToken 是统一入口它负责收敛你所有的上游渠道对外只暴露一个 Key 和一个 Base URL。两者不是替代关系是上下游关系。你本地没有 One-API 也能直接用 Ollama但那样就没有统一接口你只用 TaoToken 不接本地 Ollama 也能调云端模型但本地模型就进不来。两个一起用才能实现本地 云端一个入口。环境上我建议至少 16G 内存起步32G 更稳。纯 CPU 跑 7B 模型推理速度大概每秒几个 token做开发和调试够用别指望它扛生产流量。磁盘留 50G 以上模型文件动辄几个 G。Docker 和 Docker Compose 提前装好docker compose version能输出版本号就行。网络方面Ollama 的镜像拉取和模型下载需要能正常访问外网这一步自己确认好。另外提醒一句Ollama 默认监听 11434 端口且无鉴权千万不要直接把 11434 映射到公网。下面的配置里我会把它绑到 127.0.0.1只让本机的 One-API 容器访问。3. 可复制的 docker-compose 与环境变量配置这一节是核心直接给你能跑的配置。我建一个目录叫ai-stack里面放三个文件docker-compose.yml、.env、以及 One-API 需要的config目录首次启动会自动生成数据库。先看docker-compose.yml。这里我把 Ollama 和 One-API 放在同一个自定义网络里Ollama 的端口只绑本机回环One-API 对外暴露 3000 端口version: 3.8 services: ollama: image: ollama/ollama:latest container_name: ollama restart: always ports: - 127.0.0.1:11434:11434 volumes: - ./ollama-data:/root/.ollama networks: - ai-net environment: - OLLAMA_KEEP_ALIVE24h - OLLAMA_HOST0.0.0.0 one-api: image: justsong/one-api:latest container_name: one-api restart: always ports: - 3000:3000 volumes: - ./one-api-data:/data networks: - ai-net environment: - TZAsia/Shanghai - SESSION_SECRETchange_this_to_a_random_string depends_on: - ollama networks: ai-net: driver: bridge几个参数说明一下。OLLAMA_KEEP_ALIVE24h是让模型加载后常驻内存 24 小时避免每次请求都重新加载纯 CPU 环境下这个设置能省不少等待时间。OLLAMA_HOST0.0.0.0是让容器内监听所有网卡这样同网络的 one-api 容器才能通过服务名ollama访问到它。SESSION_SECRET换成你自己的随机串别用默认值。然后是.env文件把敏感信息和可变配置抽出来# TaoToken 统一入口 TAOTOKEN_BASE_URLhttps://taotoken.net/api TAOTOKEN_API_KEYsk-你的TaoToken密钥 # One-API 管理端 ONEAPI_ROOT_USERroot ONEAPI_ROOT_PASSWORD换成你的强密码 # Ollama 本地模型 OLLAMA_BASE_URLhttp://ollama:11434 OLLAMA_DEFAULT_MODELqwen2:7b注意OLLAMA_BASE_URL这里写的是http://ollama:11434用的是 Docker 网络里的服务名不是127.0.0.1。因为 one-api 容器和 ollama 容器在同一个ai-net网络里容器间通信用服务名解析。如果你在宿主机上直接 curl Ollama那才用127.0.0.1:11434。启动命令cd ai-stack docker compose up -d第一次启动会拉镜像Ollama 镜像比较大耐心等。启动完成后docker compose ps应该看到两个容器都是 Up 状态。然后进 Ollama 容器拉一个模型docker exec -it ollama ollama pull qwen2:7b拉完之后确认一下docker exec -it ollama ollama list能看到qwen2:7b就说明模型就位了。接下来配置 One-API。浏览器打开http://你的服务器IP:3000用.env里的 root 账号登录进渠道页面新建一个渠道类型选 Ollama渠道 API 地址填http://ollama:11434模型填qwen2:7b密钥随便填一个非空字符串Ollama 本身不校验但 One-API 表单要求必填。保存后再进令牌页面新建一个令牌复制出来。到这里本地链路就通了Ollama 提供模型 → One-API 转成 OpenAI 格式 → 对外暴露 3000 端口。下一步是把它接到 TaoToken 的统一通道上。4. 验证模型列表与对话接口连通性配置写完不验证等于没配。这一节给你几条 curl 命令从内到外逐层确认。第一层直接验证 Ollama 原生接口在宿主机执行因为端口绑了 127.0.0.1curl http://127.0.0.1:11434/api/tags返回 JSON 里能看到models数组包含qwen2:7b就对了。这一步确认 Ollama 本身活着。第二层验证 One-API 的 OpenAI 兼容接口。先拿模型列表curl http://127.0.0.1:3000/v1/models \ -H Authorization: Bearer sk-你的OneAPI令牌正常返回应该是一个data数组里面有qwen2:7b。如果返回 401说明令牌不对如果返回空数组说明渠道没配好或者模型名对不上。再验证对话接口curl http://127.0.0.1:3000/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的OneAPI令牌 \ -d { model: qwen2:7b, messages: [ {role: user, content: 用一句话介绍你自己} ], stream: false }返回里choices[0].message.content有内容就说明本地链路完全通了。注意这里stream设成false因为部分 One-API 版本在 Ollama 渠道下开流式会返回空白这个坑我在下一节细说。第三层验证 TaoToken 统一入口。把 One-API 作为上游注册到 TaoToken 之后在 TaoToken 控制台的渠道管理里添加Base URL 填你 One-API 的公网地址或内网地址Key 填 One-API 令牌用 TaoToken 的 Key 请求curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的TaoToken密钥 \ -d { model: qwen2:7b, messages: [ {role: user, content: 你好做个自我介绍} ] }如果这一步能返回内容说明从业务侧到本地 Ollama 的整条链路全部打通。之后你换云端模型只需要把model字段改成对应的模型 IDBase URL 和 Key 都不用动。想快速验证某个模型 ID 是否可用可以直接在模型对话页面里试地址是https://taotoken.net/model-chat选好模型发一条消息看返回。如果你打算长期跑编码类任务或者 Agent建议把这类高频调用放到 Coding Plan 通道上地址是https://taotoken.net/coding-plan配额和稳定性会比按次调用更合适。接入文档在https://taotoken.net/doc里面有各语言 SDK 的示例。5. 常见报错排查401、local proxy failed、reading choices这一节是我自己踩过的坑按报错信息对照排查。报错一401 Unauthorized。这个最常见出现在 curl One-API 或 TaoToken 的时候。先确认Authorization头格式对不对必须是Bearer sk-xxx中间一个空格Bearer首字母大写。然后确认 Key 有没有多余空格从控制台复制的时候容易带上换行。如果 Key 没问题检查 One-API 里令牌的额度是不是用完了或者渠道状态是不是被自动禁用了。TaoToken 侧同理去 API Keys 页面看 Key 是否被禁用。报错二local proxy failed / connection refused。这个通常出现在 One-API 请求 Ollama 的时候。原因是 One-API 容器里填的 Ollama 地址不对。如果你填的是http://127.0.0.1:11434那在容器里指向的是容器自己不是宿主机必然连不上。正确写法是http://ollama:11434用 Docker 服务名。如果两个容器不在同一个网络也会连不上检查docker-compose.yml里是不是都挂了ai-net。还有一种情况是 Ollama 容器没起来docker logs ollama看下有没有报错。报错三reading choices 时 panic 或返回空。这个是我遇到最隐蔽的一个。用流式stream: true请求 One-API 的 Ollama 渠道时返回体是空的日志里能看到解析choices字段失败。原因是部分 One-API 版本对 Ollama 的流式响应格式处理有 bug。解决办法有两个一是把 One-API 降级到 0.6.6 版本在 compose 里把镜像 tag 改成justsong/one-api:v0.6.6二是业务侧暂时用非流式请求等上游修复。我当时的做法是先降级稳定之后再考虑升级。报错四OAuth 相关报错。如果你在配置过程中看到 OAuth 字样多半是 TaoToken 控制台登录态过期或者第三方登录回调地址不对。重新登录控制台确认回调地址和你的部署域名一致。这个和 Ollama 本身无关属于账号侧问题。报错五模型名不匹配。One-API 返回model not found检查三处Ollama 里ollama list的模型名、One-API 渠道里填的模型名、请求体里的model字段三者必须完全一致包括:7b这种 tag 后缀。少一个字符都不行。排查的时候养成习惯从最内层往外层逐层 curl。先 curl Ollama 原生接口再 curl One-API最后 curl TaoToken。哪一层断了就修哪一层别一上来就怀疑最外层。6. 把统一通道用起来接入与后续链路通了之后实际接入业务代码就很简单了。不管你用 Python 的 openai SDK、Node 的 axios还是其他 HTTP 客户端只需要改三个地方Base URL 指向https://taotoken.net/apiAPI Key 用 TaoToken 的 Key模型 ID 用你在 TaoToken 侧配置好的名称。本地模型和云端模型在代码里没有任何区别切换就是改一个字符串。如果你用的是 Claude Code 这类编码工具或者 Cline 这类带 MCP 的插件配置方式也是同一套逻辑Base URL、Key、Model ID 三件套填对就行。具体到每个工具的配置文件路径和字段名接入文档里有对照表地址是https://taotoken.net/doc。需要新建或管理 Key 的时候去https://taotoken.net/console/api-keys。最后说一个实用技巧Ollama 的模型文件都存在./ollama-data目录里这个目录记得定期备份不然重新拉模型很费时间。另外OLLAMA_KEEP_ALIVE别设太长纯 CPU 环境下模型常驻内存会占掉好几个 G如果你机器上还跑着别的服务设成1h更稳妥。生产环境务必给 One-API 的 3000 端口加上反向代理和访问控制别裸奔在公网上。