Skip to main content
Glama

MCP SSH Orchestrator

by samerfarida
09-Deployment.md9.95 kB
# 9. Deployment **Purpose:** Complete guide for deploying mcp-ssh-orchestrator in production environments with security best practices. ## Overview mcp-ssh-orchestrator is designed for **containerized deployment** with security-first principles. This guide covers production deployment, scaling, and maintenance. ## Deployment Methods ### Docker (Recommended) **Single Container Deployment:** ```bash # Pull the image docker pull ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 # Run with configuration docker run -i --rm \ -v ~/mcp-ssh/config:/app/config:ro \ -v ~/mcp-ssh/keys:/app/keys:ro \ -v ~/mcp-ssh/secrets:/app/secrets:ro \ ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 ``` **Production Configuration:** ```bash # Create secure directories mkdir -p ~/mcp-ssh/{config,keys,secrets} chmod 0700 ~/mcp-ssh/secrets chmod 0400 ~/mcp-ssh/keys/* # Run with resource limits docker run -i --rm \ --memory=512m \ --cpus=1 \ --user=10001:10001 \ -v ~/mcp-ssh/config:/app/config:ro \ -v ~/mcp-ssh/keys:/app/keys:ro \ -v ~/mcp-ssh/secrets:/app/secrets:ro \ ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 ``` ### Docker Compose **Production Compose:** ```yaml version: '3.8' services: mcp-ssh: image: ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 user: "10001:10001" deploy: resources: limits: memory: 512M cpus: '1' volumes: - ./config:/app/config:ro - ./keys:/app/keys:ro - ./secrets:/app/secrets:ro healthcheck: test: ["CMD", "python", "-c", "import mcp_ssh"] interval: 30s timeout: 5s retries: 3 logging: driver: "json-file" options: max-size: "10m" max-file: "3" ``` **Development Compose:** ```yaml version: '3.8' services: mcp-ssh: build: . volumes: - ./config:/app/config:ro - ./keys:/app/keys:ro - ./secrets:/app/secrets:ro environment: - MCP_SSH_DEBUG=1 healthcheck: test: ["CMD", "python", "-c", "import mcp_ssh"] interval: 30s timeout: 5s retries: 3 ``` ## Production Setup ### 1. Configuration Setup **Create configuration directory:** ```bash mkdir -p /opt/mcp-ssh/{config,keys,secrets} chown -R 10001:10001 /opt/mcp-ssh chmod 0700 /opt/mcp-ssh/secrets chmod 0400 /opt/mcp-ssh/keys/* ``` **Copy example configurations:** ```bash cp examples/example-servers.yml /opt/mcp-ssh/config/servers.yml cp examples/example-credentials.yml /opt/mcp-ssh/config/credentials.yml cp examples/example-policy.yml /opt/mcp-ssh/config/policy.yml ``` ### 2. SSH Key Management **Generate production keys:** ```bash # Generate Ed25519 key pair ssh-keygen -t ed25519 -f /opt/mcp-ssh/keys/mcp_prod -C "mcp-ssh-orchestrator-prod" # Set permissions chmod 0400 /opt/mcp-ssh/keys/mcp_prod chmod 0444 /opt/mcp-ssh/keys/mcp_prod.pub # Deploy public key to target hosts ssh-copy-id -i /opt/mcp-ssh/keys/mcp_prod.pub ubuntu@10.0.0.11 ``` **Update credentials.yml:** ```yaml entries: - name: "prod_admin" username: "ubuntu" key_path: "mcp_prod" key_passphrase_secret: "prod_key_passphrase" password_secret: "" ``` ### 3. Policy Configuration **Production policy.yml:** ```yaml known_hosts_path: "/app/keys/known_hosts" limits: max_seconds: 30 max_output_bytes: 131072 host_key_auto_add: false require_known_host: true deny_substrings: - "rm -rf /" - "shutdown*" - "reboot*" - "systemctl restart*" - "systemctl stop*" - "systemctl start*" network: allow_cidrs: - "10.0.0.0/8" block_cidrs: - "0.0.0.0/0" require_known_host: true rules: - action: "allow" aliases: ["prod-*"] tags: ["production"] commands: - "uptime*" - "df -h*" - "systemctl status *" - "journalctl --no-pager -n 20 *" overrides: aliases: prod-db-1: max_seconds: 15 max_output_bytes: 65536 ``` ### 4. Secrets Management **Docker Secrets (Recommended):** ```bash # Create secrets echo "production-passphrase" | docker secret create mcp_prod_passphrase - echo "admin-password" | docker secret create mcp_admin_password - # Use in Docker Compose services: mcp-ssh: image: ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 secrets: - mcp_prod_passphrase - mcp_admin_password volumes: - ./config:/app/config:ro - ./keys:/app/keys:ro secrets: mcp_prod_passphrase: external: true mcp_admin_password: external: true ``` **Environment Variables:** ```bash # Set environment variables export MCP_SSH_SECRET_PROD_KEY_PASSPHRASE="production-passphrase" export MCP_SSH_SECRET_ADMIN_PASSWORD="admin-password" # Use in Docker run docker run -i --rm \ -e MCP_SSH_SECRET_PROD_KEY_PASSPHRASE \ -e MCP_SSH_SECRET_ADMIN_PASSWORD \ -v ~/mcp-ssh/config:/app/config:ro \ -v ~/mcp-ssh/keys:/app/keys:ro \ ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 ``` ## Resource Management ### Container Optimization MCP SSH Orchestrator is designed to run efficiently as a single container instance per MCP client connection. **Resource Limits:** ```yaml # docker-compose.yml services: mcp-ssh: image: ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 deploy: resources: limits: memory: 512M cpus: '1' ``` **Current Architecture:** - One container instance per MCP client (Claude Desktop, Cursor, etc.) - Stateless design allows horizontal scaling at the client level - Each MCP client connects to its own orchestrator instance - No load balancer required for single-client scenarios **Future Scaling Considerations:** - Horizontal scaling would require additional infrastructure (load balancer, shared state) - Currently not implemented - one orchestrator per MCP client is the recommended approach ### Health Monitoring **Health Check Script:** ```bash #!/bin/bash # health-check.sh # Check container health docker ps --filter "name=mcp-ssh" --filter "health=healthy" # Check MCP server responsiveness echo '{"jsonrpc":"2.0","method":"ping","id":1}' | \ docker exec -i mcp-ssh-1 python -m mcp_ssh.mcp_server stdio # Check policy configuration docker exec mcp-ssh-1 python -c " from mcp_ssh.config import Config config = Config('/app/config') print('Configuration valid:', config.validate()) " ``` **Monitoring with Prometheus:** ```yaml version: '3.8' services: mcp-ssh: image: ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 volumes: - ./config:/app/config:ro - ./keys:/app/keys:ro environment: - PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus prometheus: image: prom/prometheus ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro depends_on: - mcp-ssh ``` ## Security Hardening ### Container Security **Non-root execution:** ```dockerfile # Container runs as UID 10001 RUN useradd -u 10001 -m appuser USER appuser ``` **Resource limits:** ```yaml deploy: resources: limits: memory: 512M cpus: '1' reservations: memory: 256M cpus: '0.5' ``` **Read-only filesystem:** ```bash docker run -i --rm \ --read-only \ --tmpfs /tmp \ -v ~/mcp-ssh/config:/app/config:ro \ -v ~/mcp-ssh/keys:/app/keys:ro \ ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 ``` ### Network Security **Network isolation:** ```yaml services: mcp-ssh: image: ghcr.io/samerfarida/mcp-ssh-orchestrator:0.1.0 networks: - mcp-network volumes: - ./config:/app/config:ro - ./keys:/app/keys:ro networks: mcp-network: driver: bridge ipam: config: - subnet: 172.20.0.0/16 ``` **Firewall rules:** ```bash # Allow only necessary ports ufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw deny 2376/tcp # Docker daemon ufw deny 2377/tcp # Docker swarm ``` ## Maintenance and Updates ### Configuration Updates **Hot reload:** ```bash # Update configuration files vim /opt/mcp-ssh/config/policy.yml # Reload without restart docker exec mcp-ssh-1 python -c " from mcp_ssh.mcp_server import reload_config reload_config() " ``` **Rolling updates:** ```bash # Update to new version docker pull ghcr.io/samerfarida/mcp-ssh-orchestrator:0.2.0 # Rolling update docker service update --image ghcr.io/samerfarida/mcp-ssh-orchestrator:0.2.0 mcp-ssh ``` ### Backup and Recovery **Configuration backup:** ```bash #!/bin/bash # backup-config.sh BACKUP_DIR="/opt/backups/mcp-ssh" DATE=$(date +%Y%m%d_%H%M%S) # Create backup tar -czf "$BACKUP_DIR/config_$DATE.tar.gz" \ -C /opt/mcp-ssh config/ keys/ # Keep only last 7 days find "$BACKUP_DIR" -name "config_*.tar.gz" -mtime +7 -delete ``` **Disaster recovery:** ```bash #!/bin/bash # restore-config.sh BACKUP_FILE="$1" RESTORE_DIR="/opt/mcp-ssh" # Stop services docker-compose down # Restore configuration tar -xzf "$BACKUP_FILE" -C "$RESTORE_DIR" # Restart services docker-compose up -d ``` ## Troubleshooting ### Common Issues **Container won't start:** ```bash # Check logs docker logs mcp-ssh-1 # Check configuration docker exec mcp-ssh-1 python -c " from mcp_ssh.config import Config config = Config('/app/config') print('Config valid:', config.validate()) " ``` **SSH connection failures:** ```bash # Test SSH connectivity ssh -i /opt/mcp-ssh/keys/mcp_prod ubuntu@10.0.0.11 # Check host key verification docker exec mcp-ssh-1 ssh-keyscan 10.0.0.11 ``` **Policy issues:** ```bash # Test policy rules docker exec mcp-ssh-1 python -c " from mcp_ssh.policy import Policy policy = Policy('/app/config/policy.yml') result = policy.evaluate('prod-web-1', 'uptime', ['production']) print('Policy result:', result) " ``` ## Next Steps - **[Integrations](10-Integrations)** - MCP client setup and configuration - **[Observability & Audit](11-Observability-Audit)** - Monitoring and compliance - **[Troubleshooting](12-Troubleshooting)** - Common deployment issues - **[Security Model](05-Security-Model)** - Security architecture details

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/samerfarida/mcp-ssh-orchestrator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server