Spaces:
Sleeping
Sleeping
| title: 'Docker Setup' | |
| description: 'Deploy MCPHub using Docker and Docker Compose' | |
| # Docker Setup | |
| This guide covers deploying MCPHub using Docker, including development and production configurations. | |
| ## Quick Start with Docker | |
| ### Using Pre-built Image | |
| ```bash | |
| # Pull the latest image | |
| docker pull mcphub/mcphub:latest | |
| # Run with default configuration | |
| docker run -d \ | |
| --name mcphub \ | |
| -p 3000:3000 \ | |
| -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \ | |
| mcphub/mcphub:latest | |
| ``` | |
| ### Building from Source | |
| ```bash | |
| # Clone the repository | |
| git clone https://github.com/your-username/mcphub.git | |
| cd mcphub | |
| # Build the Docker image | |
| docker build -t mcphub:local . | |
| # Run the container | |
| docker run -d \ | |
| --name mcphub \ | |
| -p 3000:3000 \ | |
| -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \ | |
| mcphub:local | |
| ``` | |
| ### Building with Extended Features | |
| The Docker image supports an `INSTALL_EXT` build argument to include additional tools: | |
| ```bash | |
| # Build with extended features (includes Docker Engine, Chrome/Playwright) | |
| docker build --build-arg INSTALL_EXT=true -t mcphub:extended . | |
| # Option 1: Run with automatic Docker-in-Docker (requires privileged mode) | |
| docker run -d \ | |
| --name mcphub \ | |
| --privileged \ | |
| -p 3000:3000 \ | |
| -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \ | |
| mcphub:extended | |
| # Option 2: Run with Docker socket mounted (use host's Docker daemon) | |
| 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 | |
| # Verify Docker is available | |
| docker exec mcphub docker --version | |
| docker exec mcphub docker ps | |
| ``` | |
| <Note> | |
| **What's included with INSTALL_EXT=true:** | |
| - **Docker Engine**: Full Docker daemon with CLI for container management. The daemon auto-starts when the container runs in privileged mode. | |
| - **Chrome/Playwright** (amd64 only): For browser automation tasks | |
| The extended image is larger but provides additional capabilities for advanced use cases. | |
| </Note> | |
| <Warning> | |
| **Docker-in-Docker Security Considerations:** | |
| - **Privileged mode** (`--privileged`): Required for the Docker daemon to start inside the container. This gives the container elevated permissions on the host. | |
| - **Docker socket mounting** (`/var/run/docker.sock`): Gives the container access to the host's Docker daemon. Both approaches should only be used in trusted environments. | |
| - For production, consider using Docker socket mounting instead of privileged mode for better security. | |
| </Warning> | |
| ## Docker Compose Setup | |
| ### Basic Configuration | |
| Create a `docker-compose.yml` file: | |
| ```yaml | |
| version: '3.8' | |
| services: | |
| mcphub: | |
| image: mcphub/mcphub:latest | |
| # For local development, use: | |
| # 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 | |
| ``` | |
| ### Production Configuration with 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 | |
| ``` | |
| ### Environment Variables | |
| Create a `.env` file for Docker Compose: | |
| ```env | |
| # Application | |
| NODE_ENV=production | |
| JWT_SECRET=your-super-secret-jwt-key-change-this | |
| JWT_EXPIRES_IN=24h | |
| # Database | |
| POSTGRES_PASSWORD=your-secure-database-password | |
| # Redis | |
| REDIS_PASSWORD=your-secure-redis-password | |
| # External APIs | |
| OPENAI_API_KEY=your-openai-api-key | |
| # Optional: Custom port | |
| # PORT=3000 | |
| ``` | |
| ## Development Setup | |
| ### Development Docker Compose | |
| Create `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' # Frontend dev server | |
| - '9229:9229' # Debug port | |
| 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 | |
| ``` | |
| ### Development Dockerfile | |
| Create `Dockerfile.dev`: | |
| ```dockerfile | |
| FROM node:20-alpine | |
| # Install pnpm | |
| RUN npm install -g pnpm | |
| # Set working directory | |
| WORKDIR /app | |
| # Copy package files | |
| COPY package.json pnpm-lock.yaml ./ | |
| COPY frontend/package.json ./frontend/ | |
| # Install dependencies | |
| RUN pnpm install | |
| # Copy source code | |
| COPY . . | |
| # Expose ports | |
| EXPOSE 3000 5173 9229 | |
| # Start development server | |
| CMD ["pnpm", "dev"] | |
| ``` | |
| ## Running the Application | |
| ### Development Mode | |
| ```bash | |
| # Start development environment | |
| docker-compose -f docker-compose.dev.yml up -d | |
| # View logs | |
| docker-compose -f docker-compose.dev.yml logs -f mcphub-dev | |
| # Stop development environment | |
| docker-compose -f docker-compose.dev.yml down | |
| ``` | |
| ### Production Mode | |
| ```bash | |
| # Start production environment | |
| docker-compose up -d | |
| # View logs | |
| docker-compose logs -f mcphub | |
| # Stop production environment | |
| docker-compose down | |
| ``` | |
| ## Configuration Management | |
| ### MCP Settings Volume Mount | |
| Create your `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" | |
| } | |
| } | |
| } | |
| } | |
| ``` | |
| ### Secrets Management | |
| For production, use Docker secrets: | |
| ```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 | |
| ``` | |
| ## Data Persistence | |
| ### Database Backups | |
| Add backup service to your `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 | |
| ``` | |
| Create `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 created: $BACKUP_FILE" | |
| # Keep only last 7 days of backups | |
| find /backups -name "mcphub_*.sql" -mtime +7 -delete | |
| ``` | |
| Run backup: | |
| ```bash | |
| docker-compose --profile backup run --rm backup | |
| ``` | |
| ## Monitoring and Health Checks | |
| ### Health Check Endpoint | |
| Add to your application: | |
| ```javascript | |
| // In your Express app | |
| 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 Health Checks | |
| ```yaml | |
| services: | |
| mcphub: | |
| # ... other config | |
| healthcheck: | |
| test: ['CMD', 'wget', '--quiet', '--tries=1', '--spider', 'http://localhost:3000/health'] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 60s | |
| ``` | |
| ### Monitoring with Watchtower | |
| Add automatic updates: | |
| ```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 | |
| ``` | |
| ## Troubleshooting | |
| ### Common Issues | |
| **Container fails to start**: Check logs with `docker-compose logs mcphub` | |
| **Database connection errors**: Ensure PostgreSQL is healthy and accessible | |
| **Port conflicts**: Check if ports 3000/5432 are already in use | |
| **Volume mount issues**: Verify file paths and permissions | |
| ### Debug Commands | |
| ```bash | |
| # Check container status | |
| docker-compose ps | |
| # View logs | |
| docker-compose logs -f [service_name] | |
| # Execute commands in container | |
| docker-compose exec mcphub sh | |
| # Check database connection | |
| docker-compose exec postgres psql -U mcphub -d mcphub | |
| # Restart specific service | |
| docker-compose restart mcphub | |
| # Rebuild and restart | |
| docker-compose up --build -d | |
| ``` | |
| ### Performance Optimization | |
| ```yaml | |
| services: | |
| mcphub: | |
| # ... other config | |
| deploy: | |
| resources: | |
| limits: | |
| memory: 512M | |
| cpus: '0.5' | |
| reservations: | |
| memory: 256M | |
| cpus: '0.25' | |
| ``` | |
| This Docker setup provides a complete containerized environment for MCPHub with development and production configurations. | |