ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Docker部署MCP Server完整教程:容器化Claude工具服务(含docker-compose生产配置)

Docker部署MCP Server完整教程:容器化Claude工具服务(含docker-compose生产配置) 1. 为什么要把 MCP Server 塞进 DockerMCP Server 是 Claude 工具链里负责「干活」的那一层查本地 CSV、读文件、调内部接口都靠它把工具能力暴露给模型。但如果你直接在宿主机python server.py很快就会遇到几个现实问题Python 依赖和别的项目打架、服务器重启后进程不会自己起来、换台机器要重新配一遍环境、同时跑好几个 Server 时端口和进程管理一团乱。Docker 部署 MCP Server 解决的正是这些一次打包到处运行、进程自动守护、环境完全隔离、多服务编排清晰。这篇教程面向已经有一个能跑的 MCP Server、想把它容器化并稳定运行在云服务器或局域网的中级用户。我会给出可直接复制的 Dockerfile、docker-compose.yml、生产覆盖配置以及通过 TaoToken 统一 Key/API 通道接入 Claude 的配置骨架最后跑通容器启动、健康检查和 Claude 侧调用验证。整条链路的关键点有三个镜像要小且安全多阶段构建 非 root、配置要分环境开发/生产分离、日志必须写 stderrstdio 模式下写 stdout 会破坏 MCP 协议。下面按项目结构、镜像、编排、验证、排障的顺序展开。2. TaoToken 前置统一 Key 与 API 通道在容器化之前先把「模型侧」的接入方式定下来。MCP Server 本身通常不直接调模型但它依赖的上游工具链、以及 Claude 客户端连接模型时都需要一个稳定的 API 入口。我建议用 TaoToken 做统一通道好处是 Key 集中管理、Base URL 固定容器里只注入环境变量不把密钥写进镜像。你需要先拿到一个 API Key入口在控制台的 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制出来后面写进.env注意这个文件必须进.dockerignore绝不能被打进镜像层。Base URL 统一用https://taotoken.net/api这个地址不加 UTM 参数直接作为程序里的 endpoint。如果你要验证模型是否通可以先用模型对话页面发一条测试消息https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。长期跑编码类 Agent 或需要稳定额度的场景可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。把这几件事做完你手里应该有一个 Key 和一个固定的 Base URL接下来所有容器配置都围绕它们展开。3. 项目结构与可复制配置3.1 目录结构一个可维护的 MCP Server 项目建议长这样配置和代码分离环境变量有模板mcp-csv-server/ ├── Dockerfile ├── docker-compose.yml ├── docker-compose.prod.yml ├── .env ├── .env.example ├── .dockerignore ├── requirements.txt ├── server.py └── data/ └── products.csv.env.example提交到 git.env不提交。.dockerignore至少包含__pycache__/ *.pyc .env .git/ tests/ venv/ .venv/注意.env一定要写进.dockerignore。我见过有人把 Key 打进镜像层推到仓库后等于公开泄露。3.2 requirements.txtmcp1.0.0 anthropic0.40.0 pydantic2.0.0 python-dotenv1.0.03.3 Dockerfile多阶段 非 root# 阶段一依赖安装 FROM python:3.11-slim AS builder WORKDIR /build COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip \ pip install --no-cache-dir --prefix/install -r requirements.txt # 阶段二运行时镜像 FROM python:3.11-slim AS runtime RUN groupadd --gid 1000 appuser \ useradd --uid 1000 --gid appuser --shell /bin/bash --create-home appuser WORKDIR /app COPY --frombuilder /install /usr/local COPY server.py . RUN mkdir -p /app/data chown -R appuser:appuser /app USER appuser VOLUME [/app/data] ENV PYTHONIOENCODINGutf-8 LANGC.UTF-8 HEALTHCHECK --interval30s --timeout10s --start-period5s --retries3 \ CMD pgrep -f python server.py || exit 1 CMD [python, server.py]几个设计点值得说清楚多阶段构建让最终镜像不含 pip 和编译工具体积能小四成左右非 root 用户是容器安全底线单独COPY requirements.txt是为了利用层缓存代码改动不会触发依赖重装PYTHONIOENCODINGutf-8避免日志乱码。3.4 docker-compose.yml开发环境version: 3.9 services: mcp-csv: build: context: . dockerfile: Dockerfile target: runtime container_name: mcp-csv-server restart: unless-stopped env_file: - .env environment: LOG_LEVEL: DEBUG volumes: - ./data:/app/data:ro - ./server.py:/app/server.py:ro stdin_open: true tty: false logging: driver: json-file options: max-size: 10m max-file: 3stdin_open: true是 stdio 模式的关键MCP 靠标准输入输出通信stdin 必须保持开启。数据目录挂:ro只读防止容器意外改数据。3.5 docker-compose.prod.yml生产覆盖生产配置叠加在开发配置上不重复写version: 3.9 services: mcp-csv: build: cache_from: - mcp-csv-server:latest environment: LOG_LEVEL: WARNING volumes: - /data/mcp/products.csv:/app/data/products.csv:ro deploy: resources: limits: cpus: 0.5 memory: 256M reservations: cpus: 0.1 memory: 64M logging: driver: json-file options: max-size: 50m max-file: 10 labels: service,env生产环境去掉代码挂载只挂数据加上 CPU/内存限制防止单个容器把服务器吃满。3.6 .env 里的 TaoToken 配置ANTHROPIC_API_KEY你的TaoTokenKey ANTHROPIC_BASE_URLhttps://taotoken.net/api CSV_FILE/app/data/products.csv LOG_LEVELINFO容器启动时通过env_file注入程序里用os.getenv读取即可Key 不落盘到镜像。4. 构建、启动与 Claude 侧验证4.1 首次构建启动cp .env.example .env vim .env # 填入 TaoToken Key docker compose build docker compose up -d docker compose logs -f mcp-csv正常启动会看到类似输出mcp-csv-server | [MCP Server] 已加载 8 条产品数据 mcp-csv-server | [MCP Server] 等待连接...4.2 生产环境启动docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d建议设个别名省事alias dc-proddocker compose -f docker-compose.yml -f docker-compose.prod.yml dc-prod ps dc-prod logs -f4.3 健康检查与状态确认docker compose ps docker inspect --format{{.State.Health.Status}} mcp-csv-server docker stats mcp-csv-server --no-stream健康状态返回healthy说明进程存活。如果显示starting等一个检查周期再看。4.4 Claude 侧调用验证在 Claude 客户端或 Claude Code里配置 MCP Server 连接。stdio 模式下客户端会拉起容器进程并建立管道。配置片段大致如下{ mcpServers: { csv-query: { command: docker, args: [exec, -i, mcp-csv-server, python, server.py] } } }连接成功后在对话里让 Claude 调用工具比如「查一下 products.csv 里价格最高的三个产品」。如果返回了真实数据说明整条链路通了。模型侧如果报鉴权错误回到 TaoToken 控制台确认 Key 状态https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。4.5 数据热更新CSV 通过 volume 挂载更新数据后不用重启容器发个信号触发重载cp new_products.csv ./data/products.csv docker exec mcp-csv-server kill -USR1 1前提是server.py里注册了SIGUSR1处理函数重新执行load_data()。5. 本篇常见错排查容器启动后立即退出exit code 0stdio 模式下没有连接方进程正常退出这是预期行为。Claude 客户端连接时会自动拉起不用管。permission denied: /app/data/products.csv宿主机文件权限不对chmod 644 ./data/products.csv即可。No such file or directoryvolume 挂载路径写错。用docker inspect mcp-csv-server | grep -A5 Mounts确认实际挂载点。API key is not set.env没被正确加载。先docker compose config看最终生效的环境变量再检查env_file路径。日志乱码容器内没设 UTF-8Dockerfile 里加ENV PYTHONIOENCODINGutf-8 LANGC.UTF-8。镜像体积超过 500MB用了完整 Python 镜像换python:3.11-slim并启用多阶段构建。改了代码不生效开发环境检查是否挂载了./server.py:/app/server.py生产环境需要docker compose up -d --build重建。日志破坏 MCP 协议这是最容易踩的坑。stdio 模式下日志必须写 stderr写 stdout 会污染协议数据流。用logging.StreamHandler(sys.stderr)。调试时可以用这条命令不进容器看内容docker run --rm --entrypoint sh mcp-csv-server:latest -c ls -la /app cat /app/server.py6. 多 Server 编排与后续接入实际生产里往往不止一个 MCP Server。用 profiles 按需启动核心服务常驻可选服务按需拉起version: 3.9 networks: mcp-network: driver: bridge services: mcp-csv: build: ./mcp-csv restart: unless-stopped volumes: - ./data/products.csv:/app/data/products.csv:ro networks: - mcp-network mcp-files: build: ./mcp-files profiles: [full] restart: unless-stopped volumes: - /home/user/documents:/workspace:ro networks: - mcp-networkdocker compose up -d # 只启动核心 docker compose --profile full up -d # 启动全部多个 Server 共享mcp-network容器间用服务名互相访问不用暴露宿主机端口。到这里容器化 MCP Server 的完整链路就跑通了镜像构建、分环境编排、健康检查、Claude 侧调用验证。后续如果要接入更多模型能力或统一管理多个项目的 Key接入文档里有完整的参数说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。Claude Code 相关的接入细节可以看https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。控制台里可以随时查看用量和调整配置https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。
返回列表