Skip to content

在容器环境中运行 MCP

数据墙DBW 的 MCP 服务可以在容器中运行,与 REST 和 GraphQL 共享同一服务实例。本教程演示两种容器化 MCP 部署方式:HTTP 模式(远程多客户端共享)和 Stdio 模式(容器内进程通信)。

NOTE

MCP 功能要求数据墙DBW 1.7 或更高版本。

方式一:HTTP 模式(远程服务)

HTTP 模式适合将 MCP 作为远程服务暴露,多个客户端共享同一端点。

构建镜像

dockerfile
FROM ghcr.io/azure/data-api-builder:latest
COPY dab-config.json /App/dab-config.json
bash
docker build -t dab-mcp:latest .

配置文件

确保 MCP 在运行时已启用:

json
{
  "runtime": {
    "mcp": {
      "enabled": true,
      "path": "/mcp"
    },
    "rest": { "enabled": true },
    "graphql": { "enabled": true }
  }
}

三个协议在同一端口上并行运行。path 字段定义 HTTP 模式下 MCP 的端点路径。

配置文件中使用环境变量

生产环境中,连接字符串应通过环境变量注入,而非硬编码在配置文件中:

json
{
  "data-source": {
    "database-type": "mssql",
    "connection-string": "@env('SQL_CONNECTION_STRING')"
  }
}

启动容器时传入环境变量:

bash
docker run \
    --name dab-mcp \
    --publish 5000:5000 \
    --detach \
    --env "SQL_CONNECTION_STRING=Server=db-host;Database=ProductsDb;User Id=sa;Password=YourPassword;" \
    dab-mcp:latest

MCP 端点地址:http://localhost:5000/mcp

使用 MCP Inspector 验证

MCP Inspector 是 MCP 协议的调试工具,可用于验证 HTTP 模式下的 MCP 端点是否正常:

bash
npx -y @modelcontextprotocol/inspector http://localhost:5000/mcp

Inspector 通过代理模式连接,自动处理 CORS 和会话头(如 Mcp-Session-Id)兼容性问题。适用于:

  • 验证 MCP 端点是否可访问
  • 查看可用工具列表
  • 测试工具调用
  • 调试 MCP 协议消息

生产环境 JWT 认证配置

HTTP 模式下建议启用 JWT 认证:

json
{
  "runtime": {
    "host": {
      "authentication": {
        "provider": "Custom",
        "jwt": {
          "audience": "api://data-api",
          "issuer": "https://identity.example.com/"
        }
      }
    },
    "mcp": {
      "enabled": true,
      "path": "/mcp"
    }
  }
}

客户端请求时需携带有效的 Bearer Token:

bash
curl -H "Authorization: Bearer <your-jwt-token>" http://localhost:5000/mcp

多客户端共享

HTTP 模式下,多个 MCP 客户端可以同时连接同一个端点。每个客户端通过各自的认证凭据获取对应的角色权限。

生产部署要点

配置项建议
认证启用 JWT 认证,不同客户端使用不同角色
HTTPS通过反向代理(Nginx)终止 TLS
资源限制根据预期的并发 MCP 请求数设置 CPU/内存
日志生产环境日志级别 Warning,减少 I/O

方式二:Stdio 模式(容器内进程通信)

Stdio 模式适合将 MCP 服务作为容器内子进程使用。客户端启动容器并接管其标准输入/输出,服务不打开网络端口。

构建镜像

推荐使用多阶段构建,确保 .NET SDK 可用于安装 dab CLI:

dockerfile
# 构建阶段:安装 dab CLI
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
RUN dotnet tool install --global Microsoft.DataApiBuilder
ENV PATH="${PATH}:/root/.dotnet/tools"

# 运行阶段
FROM mcr.microsoft.com/dotnet/aspnet:8.0
COPY --from=build /root/.dotnet/tools /root/.dotnet/tools
COPY --from=build /root/.dotnet/tools/.store /root/.dotnet/tools/.store
ENV PATH="${PATH}:/root/.dotnet/tools"

COPY dab-config.json /App/dab-config.json
WORKDIR /App

# 不要 EXPOSE,不写 ENTRYPOINT
# 客户端直接以子进程方式启动
bash
docker build -t dab-mcp-stdio:latest .

作为容器子进程启动

客户端配置中,将 commanddab 改为通过 docker run 启动:

json
{
  "servers": {
    "sql-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--env", "SQL_CONN_STRING=Server=host.docker.internal;...",
        "--mount", "type=bind,src=./dab-config.json,dst=/App/dab-config.json,readonly",
        "dab-mcp-stdio:latest",
        "dab", "start",
        "--mcp-stdio", "role:anonymous",
        "--LogLevel", "error"
      ]
    }
  }
}

关键参数说明:

参数说明
-i保持标准输入打开(Stdio 通信必需)
--rm容器退出后自动删除
--env注入数据库连接等环境变量
--mount将本地配置文件挂载到容器中
dab start --mcp-stdio容器内启动 Stdio 模式

IMPORTANT

-i(interactive)参数必不可少——Stdio 模式需要持久的标准输入流。没有它 MCP 客户端无法与容器通信。

Docker Compose 中的 Stdio 代理

如果用 Compose 编排数据库和数据墙DBW,客户端在宿主机上时,可通过以下方式启动 Stdio 会话:

yaml
version: "3.8"
services:
  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      SA_PASSWORD: "YourPassword"

  dab-mcp:
    build: .
    environment:
      SQL_CONNECTION_STRING: "Server=db;Database=ProductsDb;User Id=sa;Password=YourPassword;"
    # 不 expose 端口,Stdio 模式不需要网络端口
    volumes:
      - ./dab-config.json:/App/dab-config.json:ro
    stdin_open: true  # 等同于 docker run -i,保持 stdin 打开
    tty: false        # Stdio 模式不需要 tty

客户端配置中,通过 docker run 启动容器作为子进程:

json
{
  "servers": {
    "sql-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm", "--network", "host",
        "--env", "SQL_CONNECTION_STRING=Server=localhost;Database=ProductsDb;...",
        "--mount", "type=bind,src=./dab-config.json,dst=/App/dab-config.json,readonly",
        "dab-mcp-stdio:latest",
        "dab", "start",
        "--mcp-stdio", "role:anonymous",
        "--LogLevel", "error"
      ]
    }
  }
}

NOTE

如果数据库也在容器中运行,需要使用 --network 参数确保 dab 容器可以访问数据库容器。使用 host 网络模式或通过自定义网络互联。

HTTP vs 容器 Stdio 选择

维度HTTP 容器Stdio 容器
网络端口开放不开放
多客户端支持每客户端独立容器
部署复杂度低(标准的 Docker 服务)中等(需客户端配合启动容器)
适用场景生产环境、远程访问、多客户端共享本地开发、IDE 集成、完全隔离场景
认证方式JWT、Simulator、网关等强制 Simulator(通过 role 参数指定角色)
水平扩展支持(负载均衡)不支持

绝大多数生产场景选择 HTTP 模式——部署简单、可水平扩展、多客户端共享。Stdio 容器模式主要用于需要完全隔离且不希望开放网络端口的特殊场景。

容器化 MCP 检查清单

检查项HTTP 模式Stdio 模式
runtime.mcp.enabled: true
连接字符串通过环境变量注入
配置文件挂载或复制到容器
容器可以连接到数据库
MCP Inspector 可连接验证
客户端配置路径使用绝对路径

下一步

数据墙DBW 产品文档与开发指南。