---
title: 'Docker 部署'
description: '使用 Docker 和 Docker Compose 部署 MCPHub'
---

# Docker 部署

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

## Docker 快速开始

### 使用预构建镜像

```bash
# 拉取最新镜像
docker pull samanhappy/mcphub:latest

# 使用默认配置运行
docker run -d \
  --name mcphub \
  -p 3000:3000 \
  -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
  samanhappy/mcphub:latest
```

### 从源码构建

```bash
# 克隆仓库
git clone https://github.com/your-username/mcphub.git
cd mcphub

# 构建 Docker 镜像
docker build -t mcphub:local .

# 运行容器
docker run -d \
  --name mcphub \
  -p 3000:3000 \
  -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
  mcphub:local
```

### 构建扩展功能版本

Docker 镜像支持 `INSTALL_EXT` 构建参数以包含额外工具：

```bash
# 构建扩展功能版本（包含 Docker 引擎，以及供 Playwright 使用的 Chrome 和 Firefox）
docker build --build-arg INSTALL_EXT=true -t mcphub:extended .

# 方式 1: 使用自动 Docker-in-Docker（需要特权模式）
docker run -d \
  --name mcphub \
  --privileged \
  -p 3000:3000 \
  -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
  mcphub:extended

# 方式 2: 挂载 Docker socket（使用宿主机的 Docker 守护进程）
docker run -d \
  --name mcphub \
  -p 3000:3000 \
  -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
  -v /var/run/docker.sock:/var/run/docker.sock \
  mcphub:extended

# 验证 Docker 可用
docker exec mcphub docker --version
docker exec mcphub docker ps
```

<Note>
  **INSTALL_EXT=true 包含的功能：**
  - **Docker 引擎**：完整的 Docker 守护进程和 CLI，用于容器管理。在特权模式下运行时，守护进程会自动启动。
  - **Chrome + Firefox（供 Playwright 使用，仅 amd64）**：用于浏览器自动化任务
  
  扩展镜像较大，但为高级用例提供了额外功能。
</Note>

<Warning>
  **Docker-in-Docker 安全注意事项：**
  - **特权模式**（`--privileged`）：容器内启动 Docker 守护进程需要此权限。这会授予容器在宿主机上的提升权限。
  - **Docker socket 挂载**（`/var/run/docker.sock`）：使容器可以访问宿主机的 Docker 守护进程。两种方式都应仅在可信环境中使用。
  - 生产环境建议使用 Docker socket 挂载而非特权模式，以提高安全性。
</Warning>

## Docker Compose 设置

### 基本配置

创建 `docker-compose.yml` 文件：

```yaml
version: '3.8'

services:
  mcphub:
    image: samanhappy/mcphub:latest
    # 本地开发时使用：
    # build: .
    container_name: mcphub
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=production
      - PORT=3000
      - JWT_SECRET=${JWT_SECRET:-your-jwt-secret}
      - DB_URL=postgresql://mcphub:password@postgres:5432/mcphub
    volumes:
      - ./mcp_settings.json:/app/mcp_settings.json:ro
      - ./servers.json:/app/servers.json:ro
      - mcphub_data:/app/data
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - mcphub-network

  postgres:
    image: pgvector/pgvector:pg17
    container_name: mcphub-postgres
    environment:
      - POSTGRES_DB=mcphub
      - POSTGRES_USER=mcphub
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql:ro
    ports:
      - '5432:5432'
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U mcphub -d mcphub']
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - mcphub-network

volumes:
  postgres_data:
  mcphub_data:

networks:
  mcphub-network:
    driver: bridge
```

### 生产配置（包含 Nginx）

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: mcphub-nginx
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
      - nginx_logs:/var/log/nginx
    depends_on:
      - mcphub
    restart: unless-stopped
    networks:
      - mcphub-network

  mcphub:
    image: samanhappy/mcphub:latest
    container_name: mcphub-app
    expose:
      - '3000'
    environment:
      - NODE_ENV=production
      - PORT=3000
      - JWT_SECRET=${JWT_SECRET}
      - JWT_EXPIRES_IN=${JWT_EXPIRES_IN:-24h}
      - DB_URL=postgresql://mcphub:${POSTGRES_PASSWORD}@postgres:5432/mcphub
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - REDIS_URL=redis://redis:6379
    volumes:
      - ./mcp_settings.json:/app/mcp_settings.json:ro
      - ./servers.json:/app/servers.json:ro
      - mcphub_data:/app/data
      - mcphub_logs:/app/logs
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - mcphub-network
    healthcheck:
      test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:3000/health']
      interval: 30s
      timeout: 10s
      retries: 3

  postgres:
    image: pgvector/pgvector:pg17
    container_name: mcphub-postgres
    environment:
      - POSTGRES_DB=mcphub
      - POSTGRES_USER=mcphub
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./backups:/backups
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U mcphub -d mcphub']
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - mcphub-network

  redis:
    image: redis:7-alpine
    container_name: mcphub-redis
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - mcphub-network

volumes:
  postgres_data:
  redis_data:
  mcphub_data:
  mcphub_logs:
  nginx_logs:

networks:
  mcphub-network:
    driver: bridge
```

### 环境变量

为 Docker Compose 创建 `.env` 文件：

```env
# 应用程序
NODE_ENV=production
JWT_SECRET=your-super-secret-jwt-key-change-this
JWT_EXPIRES_IN=24h

# 数据库
POSTGRES_PASSWORD=your-secure-database-password

# Redis
REDIS_PASSWORD=your-secure-redis-password

# 外部 API
OPENAI_API_KEY=your-openai-api-key

# 可选：自定义端口
# PORT=3000
```

## 开发设置

### 开发 Docker Compose

创建 `docker-compose.dev.yml`：

```yaml
version: '3.8'

services:
  mcphub-dev:
    build:
      context: .
      dockerfile: Dockerfile.dev
    container_name: mcphub-dev
    ports:
      - '3000:3000'
      - '5173:5173' # 前端开发服务器
      - '9229:9229' # 调试端口
    environment:
      - NODE_ENV=development
      - PORT=3000
      - DB_URL=postgresql://mcphub:password@postgres:5432/mcphub
    volumes:
      - .:/app
      - /app/node_modules
      - /app/frontend/node_modules
    depends_on:
      - postgres
    command: pnpm dev
    networks:
      - mcphub-dev

  postgres:
    image: pgvector/pgvector:pg17
    container_name: mcphub-postgres-dev
    environment:
      - POSTGRES_DB=mcphub
      - POSTGRES_USER=mcphub
      - POSTGRES_PASSWORD=password
    ports:
      - '5432:5432'
    volumes:
      - postgres_dev_data:/var/lib/postgresql/data
    networks:
      - mcphub-dev

volumes:
  postgres_dev_data:

networks:
  mcphub-dev:
    driver: bridge
```

### 开发 Dockerfile

创建 `Dockerfile.dev`：

```dockerfile
FROM node:20-alpine

# 安装 pnpm
RUN npm install -g pnpm

# 设置工作目录
WORKDIR /app

# 复制包文件
COPY package.json pnpm-lock.yaml ./
COPY frontend/package.json ./frontend/

# 安装依赖
RUN pnpm install

# 复制源代码
COPY . .

# 暴露端口
EXPOSE 3000 5173 9229

# 启动开发服务器
CMD ["pnpm", "dev"]
```

## 运行应用程序

### 开发模式

```bash
# 启动开发环境
docker-compose -f docker-compose.dev.yml up -d

# 查看日志
docker-compose -f docker-compose.dev.yml logs -f mcphub-dev

# 停止开发环境
docker-compose -f docker-compose.dev.yml down
```

### 生产模式

```bash
# 启动生产环境
docker-compose up -d

# 查看日志
docker-compose logs -f mcphub

# 停止生产环境
docker-compose down
```

## 配置管理

### MCP 设置卷挂载

创建您的 `mcp_settings.json`：

```json
{
  "mcpServers": {
    "fetch": {
      "command": "uvx",
      "args": ["mcp-server-fetch"]
    },
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest", "--headless"]
    },
    "amap": {
      "command": "npx",
      "args": ["-y", "@amap/amap-maps-mcp-server"],
      "env": {
        "AMAP_MAPS_API_KEY": "your-api-key"
      }
    }
  }
}
```

### 密钥管理

对于生产环境，使用 Docker 密钥：

```yaml
version: '3.8'

services:
  mcphub:
    image: samanhappy/mcphub:latest
    environment:
      - JWT_SECRET_FILE=/run/secrets/jwt_secret
      - DATABASE_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - jwt_secret
      - db_password

secrets:
  jwt_secret:
    file: ./secrets/jwt_secret.txt
  db_password:
    file: ./secrets/db_password.txt
```

## 数据持久化

### 数据库备份

在 `docker-compose.yml` 中添加备份服务：

```yaml
services:
  backup:
    image: pgvector/pgvector:pg17
    container_name: mcphub-backup
    environment:
      - PGPASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - ./backups:/backups
      - ./scripts/backup.sh:/backup.sh:ro
    command: /bin/sh -c "chmod +x /backup.sh && /backup.sh"
    depends_on:
      - postgres
    profiles:
      - backup
    networks:
      - mcphub-network
```

创建 `scripts/backup.sh`：

```bash
#!/bin/sh
BACKUP_FILE="/backups/mcphub_$(date +%Y%m%d_%H%M%S).sql"
pg_dump -h postgres -U mcphub -d mcphub > "$BACKUP_FILE"
echo "备份已创建：$BACKUP_FILE"

# 只保留最近 7 天的备份
find /backups -name "mcphub_*.sql" -mtime +7 -delete
```

运行备份：

```bash
docker-compose --profile backup run --rm backup
```

## 监控和健康检查

### 健康检查端点

在您的应用程序中添加：

```javascript
// 在您的 Express 应用中
app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    memory: process.memoryUsage(),
    version: process.env.npm_package_version,
  });
});
```

### Docker 健康检查

```yaml
services:
  mcphub:
    # ... 其他配置
    healthcheck:
      test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:3000/health']
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
```

### 使用 Watchtower 监控

添加自动更新：

```yaml
services:
  watchtower:
    image: containrrr/watchtower
    container_name: mcphub-watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_POLL_INTERVAL=3600
      - WATCHTOWER_INCLUDE_STOPPED=true
    restart: unless-stopped
```

## 故障排除

### 常见问题

**容器启动失败**：使用 `docker-compose logs mcphub` 检查日志

**数据库连接错误**：确保 PostgreSQL 健康且可访问

**端口冲突**：检查端口 3000/5432 是否已被占用

**卷挂载问题**：验证文件路径和权限

### 调试命令

```bash
# 检查容器状态
docker-compose ps

# 查看日志
docker-compose logs -f [service_name]

# 在容器中执行命令
docker-compose exec mcphub sh

# 检查数据库连接
docker-compose exec postgres psql -U mcphub -d mcphub

# 重启特定服务
docker-compose restart mcphub

# 重新构建并重启
docker-compose up --build -d
```

### 性能优化

```yaml
services:
  mcphub:
    # ... 其他配置
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'
        reservations:
          memory: 256M
          cpus: '0.25'
```

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