从 Ollama 迁到 Docker Model Runner 的端点对照
我实际测试了一遍「把现有 Ollama 客户端迁到 Docker Model Runner(DMR)」这件事,结论比预期更分裂:用 Ollama 原生 API 的项目几乎不用改代码,用 OpenAI 兼容 API 的项目必须改一个 base URL,而只用到 embeddings 的项目会撞上一个很隐蔽的坑——Docker 官方兼容的那个 embeddings 端点,恰恰是 Ollama 官方文档里标注「已被取代」的旧端点。
⚠️ 实测口径声明:本机没有 Docker Desktop,也没有可用 GPU,无法启动真实 DMR 服务进程。下文所有「实测」指的是 openai 3.32.0、ollama 0.6.3、httpx 0.28.1 三个官方客户端在本机发出的真实 HTTP 请求行,一共 29 组;服务端是我按 Docker 官方 api-reference 端点表实现的回放服务器,只用于判断「这条路径是否落在 DMR 公布过的路由上」。DMR 服务端的实际响应以官方文档为准,凡属文档未覆盖的行为我都单独标注了。
TL;DR:Ollama 原生客户端只改端口(11434 → 12434)就能跑通聊天与列举模型,实测请求行 POST /api/chat、GET /api/tags 都落在官方路由上;OpenAI 兼容客户端必须把 base URL 从 http://localhost:11434/v1/ 改成 http://localhost:12434/engines/v1,只换端口会发出 POST /v1/chat/completions 并拿到 404;embeddings 要改用 /api/embeddings 或 /engines/v1/embeddings,Ollama 现行的 /api/embed 在 DMR 官方文档里没有对应。
迁移代价分三档:先数清楚你要改几行
迁移前最容易犯的错,是以为「换一个端口就行」。代价完全取决于你用的是哪一层 API。按我这轮实测,可以明确分成三档:
| 档位 | 你现在的写法 | 要改什么 | 实测结果 |
|---|---|---|---|
| 零改动档 | Ollama 原生客户端(ollama SDK / curl /api/chat) | 只把端口从 11434 换成 12434 | 请求行不变,落在官方路由上 |
| 一行改动档 | OpenAI 兼容客户端(各类框架与 SDK) | base URL 从 ...:11434/v1/ 改为 ...:12434/engines/v1 | 只换端口会 404 |
| 必须重构档 | Modelfile 造模型、embeddings 管线、Responses API | 换机制,不是换地址 | 官方文档无对应端点 |
第三档是真正会让人卡住的地方。Ollama 的 ollama create -f Modelfile 在 DMR 里没有等价的 HTTP 端点,Docker 官方给的替代路径是 CLI 的 docker model package --gguf;而 embeddings 的错配更隐蔽,下面单独讲。
端点对照一:OpenAI 兼容层,`/v1` 要换成 `/engines/v1`
两边都实现了 OpenAI 兼容 API,但路径前缀完全不同,这是绝大多数 404 的来源。
| 能力 | Ollama 官方(base http://localhost:11434/v1/) | Docker Model Runner 官方(base http://localhost:12434/engines/v1) |
|---|---|---|
| 聊天 | /v1/chat/completions | /engines/v1/chat/completions |
| 文本补全 | /v1/completions | /engines/v1/completions |
| 列举模型 | /v1/models | /engines/v1/models |
| 单个模型 | /v1/models/{model} | /engines/v1/models/{namespace}/{name} |
| 向量 | /v1/embeddings | /engines/v1/embeddings |
| Responses API | /v1/responses | 官方文档未列出 |
注意最后一列的两个细节。第一,DMR 的「单个模型」路径模板是 {namespace}/{name} 两段而不是一段——官方模型名一律带 ai/ 前缀,真实路径形如 /engines/v1/models/ai/smollm2。第二,Ollama 官方文档列了 /v1/responses,DMR 的端点表里没有它;实测 client.responses.create(...) 发出 POST /engines/v1/responses,落在公布路由之外。
DMR 还允许把引擎名写进路径,变成 /engines/llama.cpp/v1/chat/completions。实测带引擎名的写法同样命中路由,这在同时跑多个推理引擎时才用得上。
另外一条官方标注的差异:DMR 官方文档写明「Token counting 使用模型原生 token 编码器,可能与 OpenAI 的不同」。如果你的代码里拿 usage 做计费或截断判断,这一条值得单独回归一次。
端点对照二:Ollama 兼容层,5 个对 15 个
Docker 官方明确写了「Ollama-compatible clients」的 base URL 就是 http://localhost:12434,不带任何路径。按官方 api-reference 的兼容端点表统计,只有 5 个:
| DMR 官方列出的 Ollama 兼容端点 | 对应 Ollama 官方端点 |
|---|---|
GET /api/tags | /api/tags |
POST /api/show | /api/show |
POST /api/chat | /api/chat |
POST /api/generate | /api/generate |
POST /api/embeddings | /api/embeddings(Ollama 已标注 superseded) |
而 Ollama 官方 docs/api.md 里一共列了 15 个端点路径:/api/generate、/api/chat、/api/create、/api/tags、/api/show、/api/copy、/api/delete、/api/pull、/api/push、/api/embed、/api/embeddings、/api/ps、/api/version,以及 /api/blobs/{sha256}(HEAD 查存在、POST 推 blob 各一个)。按文档口径,覆盖率是 5/15,约 33%。
最值得注意的一条错配:Ollama 官方文档在 /api/embeddings 那一节写了原话 this endpoint has been superseded by /api/embed,也就是说 Ollama 自己已经不推荐这个旧端点、改推 /api/embed;而 DMR 公布的兼容清单里只有旧的 /api/embeddings,没有 /api/embed。结果就是:一个按 Ollama 现行最佳实践写的 embeddings 项目,迁过去会 404。实测 ollama SDK 的 embed() 发出 POST /api/embed,落在 DMR 公布路由之外。
其余没有对应端点的能力,官方文档里也没给替代 HTTP 方案:/api/pull、/api/push 走 CLI 的 docker model pull / docker model push;/api/create(Modelfile)走 CLI 的 docker model package;/api/ps 在 HTTP 兼容层缺失,但 CLI 有 docker model ps;/api/version 对应 CLI 的 docker model version。
端点对照三:CLI 怎么换
| Ollama CLI | Docker Model Runner CLI | 备注 |
|---|---|---|
ollama pull llama3.2 | docker model pull ai/smollm2:360M-Q4_K_M | 官方示例带命名空间与量化标签 |
ollama run llama3.2 | docker model run ai/smollm2 | |
ollama list | docker model list | |
ollama ps | docker model ps | |
ollama rm | docker model rm | |
ollama show | docker model show / docker model inspect | |
ollama create -f Modelfile | docker model package --gguf ./model.gguf --push myorg/mistral-7b-v0.1:Q4_K_M | 机制不同:GGUF 打成 OCI Artifact |
| 无对应 | docker model tag / docker model push | 官方示例 docker model tag ai/smollm2 myorg/smollm2 |
| Modelfile 参数 | docker model configure --context-size 8192 ai/qwen2.5-coder | 官方 configuration 页示例 |
| 无对应 | docker model logs / docker model requests | 排障入口 |
从 Docker 官方 CLI 参考页看,docker model 有 30 多个子命令,比 ollama 的管理面更宽(df、bench、status、purge、unload、gateway 等等)。如果你的迁移动机是「想要一套更像容器工作流的管理方式」,CLI 这一层其实是加分项。
端点对照四:模型名与环境变量
改动最小,但最容易漏。
- 命名空间:Ollama 官方说模型名是
model:tag格式,命名空间可选,例子是orca-mini:3b-q8_0;DMR 官方则要求「full model identifier including the namespace」,例子是ai/smollm2、ai/llama3.2。所以smollm2要写成ai/smollm2。 - 量化标签大小写:Ollama 官方示例用小写
q8_0;DMR 官方示例用大写Q4_K_M(ai/smollm2:360M-Q4_K_M)。我没法在本机验证 DMR 服务端对大小写是否敏感,但官方示例这么写,建议照官方示例抄大写。 - 鉴权:Ollama 官方 OpenAI 兼容文档写着
api_key='ollama', # required but ignored;DMR 官方写的是「Not required. DMR ignores theAuthorizationheader」。两边都忽略 key,但客户端通常仍要求这个字段非空,留空会在 SDK 侧直接报错。 - 端口:Ollama 默认
11434;DMR 默认12434。Docker Desktop 上这个 TCP 端口默认不开,要在设置 AI 标签页勾「Enable host-side TCP support」并填端口;Docker Engine 上官方写明「TCP support is enabled by default for Docker Engine on port 12434」。 - 容器内访问:官方给了三套口径——Desktop 容器内
http://model-runner.docker.internal(不带端口),Engine 容器内http://172.17.0.1:12434,Compose 项目里可能还要加extra_hosts: "model-runner.docker.internal:host-gateway"。我本机没法验证真实环境,三套口径互不一致这件事本身,在上一篇讲 Compose 集成的文章里已经拆过。
客户端实测:29 组写法,11 组落在官方路由上
我把常见的 base URL 与 host 写法穷举了一遍,全部用真实 SDK 发真实请求,服务端按官方端点表判路由。29 组里 11 组(37.9%)落在 DMR 公布过的路径上。几种典型结果:
| 写法 | 实测请求行 | 命中官方路由 |
|---|---|---|
openai base_url=...:12434/engines/v1 | POST /engines/v1/chat/completions | 是 |
openai base_url=...:12434/engines/v1/(带尾斜杠) | POST /engines/v1/chat/completions | 是,尾斜杠不影响 |
openai base_url=...:12434(只换端口) | POST /chat/completions | 否 |
openai base_url=...:12434/v1/(Ollama 官方写法) | POST /v1/chat/completions | 否 |
openai base_url=...:12434/engines/llama.cpp/v1 | POST /engines/llama.cpp/v1/chat/completions | 是 |
ollama SDK host=...:12434 | POST /api/chat | 是 |
ollama SDK host=...:12434 + list() | GET /api/tags | 是 |
ollama SDK host=...:12434/engines/v1 | POST /engines/v1/api/chat | 否 |
ollama SDK host=...:12434 + embed() | POST /api/embed | 否 |
两条可以直接用的结论:尾斜杠不用纠结,openai SDK 对 .../engines/v1 和 .../engines/v1/ 拼出的路径完全一样;ollama SDK 的 host 里不能带路径,它会在你给的路径后面再拼 /api/xxx。
想自己复跑的话,核心就是起一个记录请求行的本地服务,再用两个 SDK 各打一遍:
import threading, http.server, socketserver
from openai import OpenAI
SEEN = []
class H(http.server.BaseHTTPRequestHandler):
def do_POST(self):
n = int(self.headers.get("Content-Length") or 0)
self.rfile.read(n)
SEEN.append(self.path) # 记录真实请求行
body = b'{"choices":[{"message":{"role":"assistant","content":"ok"}}]}'
self.send_response(200)
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
srv = socketserver.TCPServer(("127.0.0.1", 18888), H)
threading.Thread(target=srv.serve_forever, daemon=True).start()
OpenAI(base_url="http://127.0.0.1:18888/engines/v1", api_key="x", max_retries=0) \
.chat.completions.create(model="ai/smollm2", messages=[{"role": "user", "content": "hi"}])
print(SEEN) # ['/engines/v1/chat/completions']
踩坑录:5 个真实报错
下面 5 条都是本机实跑出来的。请求行与状态码是实测的;报错文案里的响应体由回放服务器生成,真实 DMR 的 404 报文可能不同,但异常类型来自官方 SDK 本身。
报错一:只换端口,`openai.NotFoundError: Error code: 404`
openai.NotFoundError: Error code: 404 - {'error': {'message': 'no route for /v1/chat/completions'}}
实测请求行是 POST /v1/chat/completions。原因:你沿用了 Ollama 官方示例里的 base_url='http://localhost:11434/v1/',只把端口换成了 12434。修法是把 base URL 整体换掉:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:12434/engines/v1", api_key="not-needed")
报错二:ollama SDK 的 host 写了路径,`ollama.ResponseError`
ollama.ResponseError: no route for /engines/v1/api/chat
实测请求行 POST /engines/v1/api/chat。原因是 Client(host=...) 会把你给的路径原样保留,再往下拼 /api/chat。修法是 host 只写到端口为止:Client(host="http://localhost:12434")。同理,写成 Client(host="http://localhost:12434/v1") 会拼出 POST /v1/api/chat,一样挂。
报错三:embeddings 端点错配,`ollama.ResponseError: no route for /api/embed`
ollama.ResponseError: no route for /api/embed
实测请求行 POST /api/embed。这是本轮最反直觉的一条:你的代码完全符合 Ollama 现行官方文档,但 DMR 公布的兼容清单里只有旧端点 /api/embeddings。两条修法——留在 Ollama 兼容层就把调用改成 /api/embeddings(注意它的参数名是 prompt,不是 /api/embed 的 input);或者干脆迁到 OpenAI 兼容层用 /engines/v1/embeddings,实测 POST /engines/v1/embeddings 命中路由。
报错四:Responses API 没有对应,`openai.NotFoundError: Error code: 404`
openai.NotFoundError: Error code: 404 - no route for /engines/v1/responses
实测请求行 POST /engines/v1/responses。Ollama 官方 openai-compatibility 文档列了 /v1/responses,DMR 端点表里没有。修法是改回 chat.completions.create(...)。
报错五:模型名只有一段,匹配不上官方路径模板
实测 models.retrieve("smollm2") 发出的请求行是 GET /engines/v1/models/smollm2,而 DMR 官方路径模板是 /engines/v1/models/{namespace}/{name} 两段。修法是把模型名写成 ai/smollm2。这条我没有在真实 DMR 上验证过失败形态(回放服务器对单段名是放行的),属于按官方路径模板推出的结论,请以你自己环境为准。
哪些场景建议先别迁
- 深度依赖 Modelfile:
ollama create -f Modelfile没有 HTTP 等价物。官方替代是docker model package --gguf,但那是把 GGUF 打包成 OCI Artifact 的另一套流程,模板、system 提示、参数都换了地方写(docker model configure)。 - 只用 embeddings 且已按新端点重写过:见报错三,你会迁到一个 Ollama 自己都标了 superseded 的端点上。
- 依赖
/api/ps的监控面板:HTTP 兼容层没有这个端点,要改成拉 CLI 的docker model ps。 - Windows 上跑 Desktop:官方明确写了要手动开 host-side TCP,否则 12434 不监听;GPU 加速还要单独勾。
FAQ
Q: 只把 11434 改成 12434,最小改动能跑通哪些功能?
A: 按本轮实测,/api/chat、/api/tags、/api/generate、/api/show、/api/embeddings 这 5 个 Ollama 原生端点都落在 DMR 官方公布路由上。前提是你走 Ollama 兼容层,并且模型名带上 ai/ 这类命名空间。
Q: OpenAI 兼容层的 base URL 到底写哪个?
A: 官方「Base URLs for third-party tools」表里分三类:OpenAI SDK 类写 http://localhost:12434/engines/v1;Anthropic SDK 类写 http://localhost:12434;Ollama 兼容客户端也写 http://localhost:12434。差别就在 /engines/v1 这个后缀。
Q: embeddings 到底该用哪个端点?
A: 留在 Ollama 兼容层就用 /api/embeddings(参数是 prompt);迁到 OpenAI 兼容层就用 /engines/v1/embeddings。Ollama 现行的 /api/embed 在 DMR 官方文档里没有对应,别用。
Q: 容器里怎么连?
A: 官方口径分三套:Desktop 容器内用 http://model-runner.docker.internal(不带端口),Engine 容器内用 http://172.17.0.1:12434,Compose 项目里可能还需要 extra_hosts。我本机起不了真实环境,建议按你用的是 Desktop 还是 Engine 二选一,再用 docker model logs 看请求。
Q: DMR 版本号怎么查?
A: 官方 get-started 页给的命令是 docker model version。我这台机器没有 Docker,无法给出具体版本号;本文涉及 DMR 的描述均来自 2026-10-17 抓取的官方文档,请以你本地 docker model version 的输出为准。
延伸阅读
- Docker Model Runner 架构解剖:三引擎与两种地址口径
- Docker Model Runner 接 Open WebUI:4 个真实故障
- 在 Compose 里声明 AI 模型:端点注入与 4 个真实报错
本文所有官方事实取自 Docker 官方 api-reference、get-started、configuration 与 CLI 参考页,以及 Ollama 官方仓库的 docs/api.md 与 docs/api/openai-compatibility.mdx,抓取时间 2026-10-17;Ollama 最新 release 为 v0.40.5(2026-10-14 发布)。价格与版本均标注「截至发稿」,请以官方页面为准。
👉 立即参与小米 MiMo 开放平台:国内领先的 AI 大模型开放平台,高性价比推理服务
👉 立即参与阿里云 AI:汇集爆款 AI 产品,热门模型专属权益优惠券助力企业创新加速
📌 本文由 AI 辅助生成并经人工审核发布 | TechPassive — AI 驱动的内容测试站点,专注于效率工具与 SaaS 真实评测
🔗 精选推荐工具
使用以下链接支持我们持续产出高质量内容(点击可直接前往购买):