1. 为什么要在 1Panel 里把 Nacos、Ollama、vLLM、MCP 凑成一套
如果你手上有一台带显卡的服务器,想跑一套能自己掌控的 AI 服务,大概率会经历这样的过程:先装个 Ollama 试试本地模型,觉得不错;再想上 vLLM 提升吞吐,结果发现端口、网络、模型路径全要重新理;等模型多了,又想让 Cline、CC Switch 这类编码工具统一调用,于是开始折腾 MCP 和注册中心。最后服务是跑起来了,但容器之间互相 ping 不通、Nacos 收不到注册、vLLM 认不到 GPU,排错排到怀疑人生。
这篇教程就是把这条链路一次讲清楚:用 1Panel 面板做可视化管理,同时给出命令行方式,把 Nacos 3.2.2 作为注册配置中心、Ollama 作为轻量推理、vLLM 作为 GPU 高性能推理、MCP 作为工具链网关全部容器化,并且通过 TaoToken 的统一 Key 和 API 通道,让 Cline、CC Switch 这类客户端只配一个地址就能调用多个模型。适合已经装好 1Panel、想搭私有 AI 服务栈的运维和开发者,也适合刚接触容器编排、想跟着敲一遍的新手。
整套架构的核心思路是:所有容器接入同一个自定义网桥,用容器名做 DNS 互相访问,Nacos 负责服务注册与发现,MCP 网关把 Ollama 和 vLLM 包装成标准 MCP 服务注册进 Nacos,客户端通过 Nacos 或直连 SSE 地址调用。下面按「前置准备 → 逐个部署 → 验证 → 排错」的顺序展开,命令和配置都可以直接复制。
2. TaoToken 前置:统一 Key 与 API 通道怎么接
在开始部署容器之前,先把 TaoToken 这一层理清楚,不然后面客户端配置会乱。TaoToken 的作用是提供一个统一的 API 入口和 Key 管理,你不需要在 Cline、CC Switch、OpenWebUI 里分别填 Ollama、vLLM、云端模型的地址,而是通过一个兼容 OpenAI 协议的通道统一调用。
官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基础地址是 https://taotoken.net/api ,注意 API 地址后面不加 UTM 参数。你需要先去控制台创建一个 API Key,控制台入口在 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,Key 管理页面在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。
拿到 Key 之后,客户端里填的 base_url 就是https://taotoken.net/api,api_key 填你创建的那串。如果你只是想先验证模型能不能通,可以直接用模型对话页面 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 试一下,不用写代码。如果你打算长期用编码工具或 Agent,建议看一下 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它针对高频编码场景做了额度优化。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,遇到协议细节可以查。
这里要强调一点:TaoToken 是作为统一的 API 通道来用的,不是替代你的编辑器或推理服务。Ollama 和 vLLM 仍然跑在你自己的服务器上,TaoToken 负责的是客户端到模型之间的统一接入层。这样你在 Cline 里切换本地模型和云端模型时,只需要改一个 model 名字,不用改 base_url。
3. 前置准备:网络规划与基础校验
3.1 基础环境校验
登录服务器终端,先确认三件事:Docker 可用、GPU 可识别(如果有显卡)、1Panel 服务正常。
# 检查 Docker 版本 docker --version # 检查 1Panel 服务状态 systemctl status 1panel # GPU 环境校验(无显卡跳过) docker run --rm --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi第三条命令如果报错,说明 nvidia-docker2 没装好或者驱动版本不匹配。注意看nvidia-smi输出右上角的 CUDA Version,后面选 vLLM 镜像版本要以它为准。比如显示 CUDA Version: 12.6,就选支持 12.6 的 vLLM 镜像,选错了容器会直接退出。
3.2 规划固定网络与端口
先看当前 Docker 网络情况:
# 列出所有网络 docker network ls # 查看某个网络的详细信息,包括网段和已用 IP docker network inspect 1panel-network1Panel 默认会创建一个1panel-network,网段通常是 172.21.0.0/16。我们沿用这个网桥,给每个容器分配固定 IP,保证重启后地址不变。规划如下:
| 服务名称 | 容器内网 IP | 宿主机端口 | 备注 |
|---|---|---|---|
| Nacos | 172.21.0.5 | 8848/9848 | 注册配置中心 |
| Ollama | 172.21.0.3 | 11434 | 轻量推理 |
| vLLM | 172.21.0.6 | 8000 | GPU 高性能推理 |
| MCP-Ollama | 172.21.0.8 | 8200 | Ollama 的 MCP 网关 |
| MCP-vLLM | 172.21.0.9 | 8100 | vLLM 的 MCP 网关 |
如果你不想用 1panel-network,也可以在 1Panel 后台「容器 → 网络」里新建一个,比如叫ai-mcp-net,子网 172.20.0.0/16,网关 172.20.0.1。自定义网桥的好处是容器名可以直接当域名用,不用记 IP,而且不同网桥之间天然隔离,比默认 bridge 安全。
4. 可复制配置:逐个部署四个核心服务
4.1 部署 Nacos 3.2.2(注册配置中心)
Nacos 是整个栈的服务注册中心,MCP 网关启动后会把自己的 SSE 地址注册进来,客户端通过 Nacos 做服务发现。
1Panel 面板方式:进入「容器 → 容器管理 → 创建容器」,基础配置填容器名nacos,镜像nacos/nacos-server:v3.2.2,重启策略选「总是重启」。端口映射加 8848→8848 和 9848→9848。数据卷把本地目录/opt/1panel/volumes/nacos-data挂到容器/home/nacos/data。网络选1panel-network,IPv4 地址填 172.21.0.5。环境变量加MODE=standalone、NACOS_AUTH_ENABLE=true、NACOS_CORE_AUTH_USERNAME=nacos、NACOS_CORE_AUTH_PASSWORD=nacos。点创建并启动。
命令行方式:如果你习惯敲命令,用 docker run 带持久化启动:
mkdir -p /data/nacos/{logs,data,conf} docker run -d \ --name nacos \ --restart always \ --network 1panel-network \ --ip 172.21.0.5 \ -p 8848:8848 \ -p 9848:9848 \ -p 9849:9849 \ -e MODE=standalone \ -e NACOS_AUTH_ENABLE=true \ -e NACOS_CORE_AUTH_USERNAME=nacos \ -e NACOS_CORE_AUTH_PASSWORD=nacos \ -v /data/nacos/logs:/home/nacos/logs \ -v /data/nacos/data:/home/nacos/data \ nacos/nacos-server:v3.2.2启动后访问http://服务器IP:8848/nacos,账号密码都是 nacos。登录后进入「AI 管理中心 → MCP 管理」,把「启用 MCP Registry」打开,这一步很关键,不开的话 MCP 服务注册不进来。
4.2 部署 Ollama(轻量推理)
Ollama 用来跑小参数模型,适合快速验证和低并发场景。
1Panel 面板方式:创建容器,名称ollama-mcp,镜像ollama/ollama:latest,重启策略「总是重启」。端口 11434→11434。数据卷本地目录/opt/1panel/volumes/ollama-data挂到/root/.ollama。网络选1panel-network,IP 填 172.21.0.3。在「高级选项 → 启动命令」里填:
sh -c "ollama serve && sleep 10 && ollama pull qwen3:4b && wait"这样容器启动后会自动拉取 qwen3:4b 模型。如果你不想自动拉,把 pull 那段去掉,启动后手动进容器拉。
命令行方式:
docker run -d \ --name ollama-mcp \ --restart always \ --network 1panel-network \ --ip 172.21.0.3 \ -p 11434:11434 \ -v /opt/1panel/volumes/ollama-data:/root/.ollama \ ollama/ollama:latest启动后手动拉模型:
docker exec -it ollama-mcp ollama pull qwen3:4b docker exec -it ollama-mcp ollama list4.3 部署 vLLM(GPU 高性能推理)
vLLM 只在有 NVIDIA 显卡时部署,它的吞吐比 Ollama 高很多,适合生产环境。镜像版本一定要和你的 CUDA 版本匹配,前面nvidia-smi看到的是 12.6,就选支持 12.6 的镜像。
1Panel 面板方式:创建容器,名称vllm-mcp,镜像vllm/vllm-openai:v0.7.3(按你的 CUDA 版本调整)。端口 8000→8000。网络1panel-network,IP 172.21.0.6。在「高级选项」里勾选「启用 GPU」,选「全部显卡」。启动命令填:
--model Qwen3-4B --host 0.0.0.0 --port 8000 --api-key sk-vllm-nacos-322命令行方式:
docker run -d \ --name vllm-mcp \ --restart always \ --network 1panel-network \ --ip 172.21.0.6 \ -p 8000:8000 \ --gpus all \ -v /opt/1panel/volumes/vllm-cache:/root/.cache/huggingface \ vllm/vllm-openai:v0.7.3 \ --model Qwen3-4B \ --host 0.0.0.0 \ --port 8000 \ --api-key sk-vllm-nacos-322如果显存不够,加--gpu-memory-utilization 0.7降低占用。启动后验证:
curl http://127.0.0.1:8000/v1/models返回模型列表就说明 vLLM 起来了。
4.4 部署 MCP 网关(把 Ollama 和 vLLM 注册进 Nacos)
MCP 网关的作用是把 Ollama 和 vLLM 包装成标准 MCP 服务,自动注册到 Nacos。先建目录结构:
ai-stack/ ├── docker-compose.yml ├── mcp-ollama/ │ ├── Dockerfile │ ├── requirements.txt │ └── main.py └── mcp-vllm/ ├── Dockerfile ├── requirements.txt └── main.py两个目录的 Dockerfile 和 requirements.txt 完全一样:
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY main.py . EXPOSE 8200 ENV PYTHONUNBUFFERED=1 CMD ["python", "main.py"]mcp[sse] starlette uvicorn openai pydantic>=2.0 nacos-mcp-wrapper-pythonmcp-ollama/main.py内容:
from nacos_mcp_wrapper.server.nacos_mcp import NacosMCP from nacos_mcp_wrapper.server.nacos_settings import NacosSettings from openai import OpenAI, APIError from pydantic import BaseModel nacos_settings = NacosSettings() nacos_settings.SERVER_ADDR = "nacos:8848" nacos_settings.NAMESPACE = "public" nacos_settings.USERNAME = "nacos" nacos_settings.PASSWORD = "nacos" SERVICE_NAME = "ollama-mcp-nacos322" ollama_client = OpenAI( base_url="http://ollama-mcp:11434/v1", api_key="dummy", timeout=120.0 ) class ChatReq(BaseModel): prompt: str model: str = "qwen3:4b" mcp = NacosMCP(SERVICE_NAME, nacos_settings=nacos_settings) @mcp.tool() async def llm_chat(req: ChatReq) -> str: """调用Ollama大模型对话""" try: resp = ollama_client.chat.completions.create( model=req.model, messages=[{"role": "user", "content": req.prompt}] ) return resp.choices[0].message.content.strip() except APIError as e: return f"Ollama调用异常:{str(e)}" if __name__ == "__main__": mcp.run(transport="sse")mcp-vllm/main.py把 base_url 改成http://vllm-mcp:8000/v1,api_key 改成sk-vllm-nacos-322,SERVICE_NAME 改成vllm-mcp-nacos322,模型默认值改成Qwen3-4B。
然后写docker-compose.yml:
version: "3.8" networks: 1panel-network: external: true services: mcp-ollama: build: ./mcp-ollama container_name: mcp-ollama restart: always networks: - 1panel-network ports: - "8200:8200" environment: NACOS_SERVER_ADDR: "nacos:8848" NACOS_NAMESPACE: "public" NACOS_USERNAME: "nacos" NACOS_PASSWORD: "nacos" mcp-vllm: build: ./mcp-vllm container_name: mcp-vllm restart: always networks: - 1panel-network ports: - "8100:8100" environment: NACOS_SERVER_ADDR: "nacos:8848" NACOS_NAMESPACE: "public" NACOS_USERNAME: "nacos" NACOS_PASSWORD: "nacos"注意1panel-network声明为 external,因为它是 1Panel 已经创建好的,compose 不要重复创建。启动:
cd ai-stack docker compose up -d docker logs mcp-ollama -f看到Register MCP Server to Nacos success就说明注册成功。
5. 验证请求与成功结果
5.1 验证 Nacos 服务注册
浏览器打开http://服务器IP:8848/nacos,登录后进「AI 管理中心 → MCP 管理 → MCP 服务列表」,应该能看到ollama-mcp-nacos322和vllm-mcp-nacos322两个服务,健康状态正常,实例地址是容器内网 SSE 地址。
5.2 验证 Ollama 接口
curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"qwen3:4b","messages":[{"role":"user","content":"你好"}]}'返回 JSON 里 choices 字段有内容就说明通了。
5.3 验证 vLLM 接口
curl http://127.0.0.1:8000/v1/completions \ -H "Content-Type: application/json" \ -d '{"model":"Qwen3-4B","prompt":"用中文介绍杭州","max_tokens":100,"temperature":0.7}'有返回文本就说明 vLLM 正常。小参数模型输出逻辑可能有点怪,这是模型本身的问题,不影响接口验证。
5.4 验证 MCP SSE 地址
curl http://127.0.0.1:8200/mcp/messages curl http://127.0.0.1:8100/mcp/messages能返回 SSE 事件流就说明 MCP 网关正常。
5.5 客户端配置:Cline 与 CC Switch
在 Cline 的 MCP 配置里,直连方式填:
{ "mcpServers": { "ollama-local": { "url": "http://服务器IP:8200/mcp/messages", "transport": "sse" }, "vllm-local": { "url": "http://服务器IP:8100/mcp/messages", "transport": "sse" } } }如果你用 CC Switch 或 Claude Code 这类工具,通过 TaoToken 统一接入时,settings.json 里填:
{ "apiBase": "https://taotoken.net/api", "apiKey": "你的TaoToken Key", "model": "qwen3-4b" }这样本地模型和云端模型走同一个入口,切换只改 model 字段。Claude Code 的接入细节可以参考 https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claude-code&utm_campaign=rewrite 。
6. 本篇常见错排查
坑 1:MCP 注册 401 鉴权失败。Nacos 3.2.2 强制校验NACOS_AUTH_IDENTITY_KEY和NACOS_AUTH_IDENTITY_VALUE,compose 里少这两个变量会直接拒绝注册。把鉴权相关的环境变量补全。
坑 2:MCP 服务连不上 nacos:8848。先确认所有容器都在同一个网桥,然后进容器测试连通性:
docker exec -it mcp-vllm ping nacos代码里的地址绝对不能写 127.0.0.1 或宿主机 IP,必须写容器名。
坑 3:vLLM 容器启动失败、GPU 识别异常。检查 1Panel 容器配置里有没有勾选 GPU,重装 nvidia-docker2 后重启 Docker,显存不够就加--gpu-memory-utilization 0.7。
坑 4:Nacos 收不到 MCP 注册。确认 8848 端口放行,Nacos 后台「启用 MCP Registry」已打开,MCP 容器日志里有没有报连接超时。
坑 5:容器之间无法互通。确认所有容器都加入了同一个自定义网桥,检查固定 IP 有没有冲突,临时关掉宿主机防火墙测试。
坑 6:代码修改后不生效。MCP 代码是 COPY 进镜像的,改完要重新 build:
docker compose build mcp-ollama docker compose up -d mcp-ollama7. 长期编码与 Agent 场景的接入建议
如果你只是偶尔验证模型,用模型对话页面就够了。但如果你打算把 Cline、CC Switch 这类工具长期挂在项目里跑,建议走 Coding Plan,额度和稳定性更适合高频调用。接入文档里有完整的协议说明和示例,遇到 base_url 或 model 名字对不上,先查文档再改配置。
整套栈跑通之后,日常运维在 1Panel 面板里点几下就行:看容器状态、翻日志、进终端、重启服务。端口和防火墙在「安全 → 防火墙」里统一放行 8848、9848、11434、8000、8100、8200。想加前端界面的话,再起一个 OpenWebUI 容器,镜像ghcr.io/open-webui/open-webui:main,端口 3030→3000,网络加入同一个网桥,后台配 Ollama 和 vLLM 地址就能用。
最后提醒一句:MCP 网关的代码里,Nacos 地址和模型服务地址都用容器名,不要图省事写 IP,容器重建后 IP 可能变,容器名是稳定的。这套配置我反复重建过几次,只要网桥和容器名不变,起来就能用。