Skip to main content

Docker 部署

本指南介绍使用 Docker 部署 MCPHub,包括开发和生产配置。

Docker 快速开始

使用预构建镜像

标准 MCPHub 镜像内置 Node.js/pnpm、Python、uv/uvx、Git 和构建工具。如果需要为 Rust MCP server 使用 Cargo 和稳定版 Rust 工具链,请使用 latest-full 镜像。
镜像默认使用 /app/data/mcp_settings.json。挂载整个数据目录可持久化配置、用户、凭据绑定及其加密密钥。如需自定义服务器,可在首次启动前创建 data/mcp_settings.json,或在启动后编辑现有文件。后台运行(-d)时,通过 docker logs mcphub 查看首次生成的管理员密码。 启动时会自动识别旧方式挂载的 /app/mcp_settings.json,并优先于数据目录使用,因此原有 Docker 命令无需修改。显式设置的 MCPHUB_SETTING_PATH 始终拥有最高优先级。为完整持久化数据,应将配置文件及已有的 .credentials.json、.credentials.key 伴随文件一起迁入挂载的数据目录。仍支持显式覆盖 MCPHUB_SETTING_PATH。

从源码构建

构建扩展功能版本

Docker 镜像支持 INSTALL_EXT 构建参数以包含额外工具。发布的 -full 镜像会启用此参数:
INSTALL_EXT=true 包含的功能:
  • 稳定版 Rust + Cargo:通过 rustup 安装,用于基于 Rust 的 MCP server。
  • Docker 引擎:完整的 Docker 守护进程和 CLI,用于容器管理。在特权模式下运行时,守护进程会自动启动。
  • Chrome + Firefox(供 Playwright 使用,仅 amd64):用于浏览器自动化任务
扩展镜像较大,但为高级用例提供了额外功能。
Docker-in-Docker 安全注意事项:
  • 特权模式(--privileged):容器内启动 Docker 守护进程需要此权限。这会授予容器在宿主机上的提升权限。
  • Docker socket 挂载(/var/run/docker.sock):使容器可以访问宿主机的 Docker 守护进程。两种方式都应仅在可信环境中使用。
  • 生产环境建议使用 Docker socket 挂载而非特权模式,以提高安全性。

Docker Compose 设置

基本配置

创建 docker-compose.yml 文件:

持久化 stdio 包缓存

stdio 服务器在首次使用时会下载并安装对应的包:npx 使用 npm 的缓存,uvx 以及其他基于 uv 的命令使用 uv 的缓存。镜像未设置 USER,因此以 root 运行,这些安装内容位于: uv tool install 创建的环境位于 ~/.local/share/uv/tools,它们烘焙在镜像层中,不受这里的 讨论影响。如果你以非 root 用户运行镜像,~ 就不是 /root:上表中的路径与下文的挂载目标都需 要改成该用户的家目录。 这些路径默认都不是卷,因此只存在于容器的可写层。而可写层会在容器被重建时丢弃——升级镜像、 执行 docker compose down && up -d,或修改任何服务配置都会触发重建。下次启动时,所有 stdio 服务器会同时从零重新安装,之后才能开始各自的 MCP 握手。
docker restart 保留可写层,因此不会丢失缓存;而 docker compose down 后再 up -d 会删除并重建容器,缓存随之消失。如果你发现”重启后似乎重装了所有东西”,通常就是这个区别。
把这两个路径挂载出来,安装内容就会保存在宿主机上:
具名卷可以在 docker compose down 后保留,只有 down -v 才会删除。绑定挂载 (./data/npm-cache:/root/.npm)同样可行,也更方便手动查看或清理,但它不会像具名卷那样用镜像 中该路径的内容初始化——而是直接遮蔽掉镜像里已有的东西。在 amd64 上,-full 镜像会在 /root/.npm/_npx 中预装 Playwright,因此在该路径使用绑定挂载意味着要重新下载一次。 几点值得注意:
  • 不需要锁定版本。 未指定版本的 npx -y <package> 会直接复用缓存中已安装的包,而不会重新 安装。但 npm 每次运行仍会向 registry 重新校验包的元数据,因此 registry(或你的代理)必须保持 可达——缓存省下的是安装成本,不是这一次网络往返。
  • 挂载后的第一次启动仍然是冷的。 卷刚创建时是空的,这一次需要付出完整的安装成本;此后每次 重建都会复用它。
  • 预留足够空间。 约 90 个 stdio 服务器大致占用 2 GB。
  • 安装内容损坏时,请使用该服务器的「重新安装」操作——仅 npx 与 uvx 服务器支持。对 uvx 而言,它只刷新那一个包(在下次启动时注入 --refresh 参数);对 npx 而言,它会删除 整个共用的 /root/.npm/_npx 目录,因此下次启动时所有 npx 服务器都会重新安装,而不只是 你指定的那一个。_cacache 卷的作用就是让这次重装的代价变小。
规模越大影响越明显。在一个约 95 个 stdio 服务器的部署中,冷启动重建后只有 19 个连接成功, 74 个因 MCP error -32001: Request timed out 连接失败,因为所有服务器都在同时安装、互相争抢 资源。挂载缓存后,同一次重启达到 73 个连接成功且没有任何超时——但那次运行同时把 INIT_TIMEOUT 从默认的 300000 提高到了 900000,所以这两项改动必须分开看。按每分钟的连接曲线粗略拆分:缓存在 原本 300 秒的预算内约值 +45 台,更长的超时约值 +9 台。主要成本是重新安装包,而不是等待。

生产配置(包含 Nginx)

环境变量

为 Docker Compose 创建 .env 文件:

开发设置

开发 Docker Compose

创建 docker-compose.dev.yml:

开发 Dockerfile

创建 Dockerfile.dev:

运行应用程序

开发模式

生产模式

配置管理

MCP 设置卷挂载

首次启动前,创建 data/mcp_settings.json:

密钥管理

对于生产环境,使用 Docker 密钥:

数据持久化

数据库备份

在 docker-compose.yml 中添加备份服务:
创建 scripts/backup.sh:
运行备份:

监控和健康检查

健康检查端点

在您的应用程序中添加:

Docker 健康检查

使用 Watchtower 监控

添加自动更新:

故障排除

常见问题

容器启动失败:使用 docker-compose logs mcphub 检查日志 数据库连接错误:确保 PostgreSQL 健康且可访问 端口冲突:检查端口 3000/5432 是否已被占用 卷挂载问题:验证文件路径和权限

调试命令

性能优化

此 Docker 设置为 MCPHub 提供了完整的容器化环境,包含开发和生产配置。