Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mcphub.app/llms.txt

Use this file to discover all available pages before exploring further.

Docker Setup

This guide covers deploying MCPHub using Docker, including development and production configurations.

Quick Start with Docker

Using Pre-built Image

# Pull the latest image
docker pull samanhappy/mcphub:latest

# Run with default configuration
docker run -d \
  --name mcphub \
  -p 3000:3000 \
  -v $(pwd)/mcp_settings.json:/app/mcp_settings.json \
  samanhappy/mcphub:latest

Building from Source

# 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:
# Build with extended features (includes Docker Engine, Chrome + Firefox for 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
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 + Firefox for Playwright (amd64 only): For browser automation tasks
The extended image is larger but provides additional capabilities for advanced use cases.
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.

Docker Compose Setup

Basic Configuration

Create a docker-compose.yml file:
version: '3.8'

services:
  mcphub:
    image: samanhappy/mcphub:latest
    # For local development, use:
    # build: .
    container_name: mcphub
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=production
      - PORT=3000
      - TRUST_PROXY=1
      - 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

Production Configuration with Nginx

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
      - TRUST_PROXY=1
      - 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

Environment Variables

Create a .env file for Docker Compose:
# Application
NODE_ENV=production
TRUST_PROXY=1
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:
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
      - 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

Development Dockerfile

Create Dockerfile.dev:
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

# 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

# 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:
{
  "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:
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

Data Persistence

Database Backups

Add backup service to your docker-compose.yml:
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
Create scripts/backup.sh:
#!/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:
docker-compose --profile backup run --rm backup

Monitoring and Health Checks

Health Check Endpoint

Add to your application:
// 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

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:
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 Rate-limit warning about X-Forwarded-For: Set TRUST_PROXY=1 when MCPHub is behind Nginx, Traefik, a load balancer, or another reverse proxy. Recent versions also default to trusting one proxy automatically inside Docker/Kubernetes, but keeping it explicit in production compose files is recommended. 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

# 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

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.