MCP Server Docker 隔离实践:文件、网络、Token 和权限边界

本文记录一套 MCP Server 接入团队 AI 编程工具前的 Docker 隔离检查。目标不是讲 MCP 协议入门,而是避免 MCP Server 直接继承主机权限,导致文件、网络、Token 和镜像来源不可控。

1. 适用场景

假设团队准备接入这些 MCP Server:

  • Git / 文件系统 Server。
  • 数据库查询 Server。
  • 浏览器自动化 Server。
  • 内部 API 查询 Server。

如果这些 Server 直接跑在开发机或服务器主机上,默认可能看到主机文件、环境变量、网络和本地凭据。上线前建议先容器化,再开放给团队使用。

2. 先做镜像预检

先确认基础运行时能稳定拉取:

bash 复制代码
docker pull docker.1ms.run/node:22-alpine
docker pull docker.1ms.run/python:3.12-slim
docker pull docker.1ms.run/redis:7

这一步用于排除镜像来源问题。MCP Server 后续如果启动失败,至少可以先确认不是基础镜像拉取导致。

3. 文件类 MCP Server:默认无网络

文件类 Server 不一定需要访问外网,建议先禁用网络,只挂载明确目录:

yaml 复制代码
services:
  mcp-files:
    image: docker.1ms.run/node:22-alpine
    user: "1000:1000"
    working_dir: /workspace
    read_only: true
    network_mode: "none"
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    volumes:
      - ./server:/app:ro
      - ./workspace:/workspace:ro
      - ./mcp-tmp:/tmp:rw
    command: ["node", "/app/server.js"]

注意点:

  • 不要挂载整个 $HOME
  • 不要把 ~/.ssh、云厂商凭据、浏览器 profile 放进去。
  • workspace 优先只读,确实需要写入时再拆出单独目录。

4. 数据库类 MCP Server:只进指定网络

数据库类 Server 不需要访问所有内网,只需要访问数据库所在网络:

yaml 复制代码
networks:
  mcp-db-net:
    internal: true

services:
  mcp-db:
    image: docker.1ms.run/python:3.12-slim
    user: "1000:1000"
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    networks:
      - mcp-db-net
    volumes:
      - ./server:/app:ro
    env_file:
      - ./secrets/mcp-db.env
    command: ["python", "/app/server.py"]

secrets/mcp-db.env 里不要放全库管理员账号,优先使用只读账号、最小库表权限和短期 Token。

5. 检查表

检查项 命令或动作
镜像来源 固定 image、tag,必要时记录 digest
容器用户 检查是否非 root
文件系统 read_only: true,只挂必要目录
网络出口 文件类默认 network_mode: none
Linux 权限 cap_drop: [ALL]
提权限制 no-new-privileges:true
凭据 env 文件权限收紧,不进镜像
日志 不打印 Token、Cookie、连接串

6. 结论

MCP Server 接入 AI 工具前,先把边界讲清楚。Docker 沙箱不能代替完整安全治理,但它能把最容易失控的目录、网络、权限和镜像来源先收住。镜像拉取、运行时版本和依赖组件可以用毫秒镜像做预检;真正的安全边界,还要靠最小权限、网络策略、secret 管理和审计一起完成。