--- title: 'Docker 部署' description: '使用 Docker 和 Docker Compose 部署 MCPHub' --- # Docker 部署 本指南介绍使用 Docker 部署 MCPHub,包括开发和生产配置。 ## Docker 快速开始 ### 使用预构建镜像 ```bash # 拉取最新镜像 docker pull mcphub/mcphub:latest # 使用默认配置运行 docker run -d \ --name mcphub \ -p 3000:3000 \ -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \ mcphub/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 引擎、Chrome/Playwright) 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 ``` **INSTALL_EXT=true 包含的功能:** - **Docker 引擎**:完整的 Docker 守护进程和 CLI,用于容器管理。在特权模式下运行时,守护进程会自动启动。 - **Chrome/Playwright**(仅 amd64):用于浏览器自动化任务 扩展镜像较大,但为高级用例提供了额外功能。 **Docker-in-Docker 安全注意事项:** - **特权模式**(`--privileged`):容器内启动 Docker 守护进程需要此权限。这会授予容器在宿主机上的提升权限。 - **Docker socket 挂载**(`/var/run/docker.sock`):使容器可以访问宿主机的 Docker 守护进程。两种方式都应仅在可信环境中使用。 - 生产环境建议使用 Docker socket 挂载而非特权模式,以提高安全性。 ## Docker Compose 设置 ### 基本配置 创建 `docker-compose.yml` 文件: ```yaml version: '3.8' services: mcphub: image: mcphub/mcphub:latest # 本地开发时使用: # build: . container_name: mcphub ports: - '3000:3000' environment: - NODE_ENV=production - PORT=3000 - JWT_SECRET=${JWT_SECRET:-your-jwt-secret} - DATABASE_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: postgres:15-alpine 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: mcphub/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} - DATABASE_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: postgres:15-alpine 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 - DATABASE_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: postgres:15-alpine 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: mcphub/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: postgres:15-alpine 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 提供了完整的容器化环境,包含开发和生产配置。