Skip to main content
Glama

Secure MCP Server

docker-compose.yml8.11 kB
version: '3.9' x-app-common: &app-common restart: unless-stopped networks: - secure-mcp logging: driver: "json-file" options: max-size: "10m" max-file: "3" services: # Main application app: <<: *app-common build: context: . dockerfile: Dockerfile target: production cache_from: - node:20.11.0-alpine3.19 image: secure-mcp-server:latest container_name: secure-mcp-app ports: - "3000:3000" environment: NODE_ENV: ${NODE_ENV:-development} DATABASE_URL: postgresql://mcp_user:${DB_PASSWORD:-SecurePass123!}@postgres:5432/mcp_db?schema=public&sslmode=require REDIS_URL: redis://:${REDIS_PASSWORD:-RedisPass123!}@redis:6379/0 JWT_SECRET: ${JWT_SECRET:-development-secret-change-in-production} VAULT_ADDR: http://vault:8200 VAULT_TOKEN: ${VAULT_TOKEN:-development-token} LOG_LEVEL: ${LOG_LEVEL:-info} CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000} RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000} RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-100} depends_on: postgres: condition: service_healthy redis: condition: service_healthy vault: condition: service_started volumes: - app-logs:/app/logs:rw - app-tmp:/app/tmp:rw security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - SETUID - SETGID read_only: true tmpfs: - /tmp:noexec,nosuid,size=100M healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s # PostgreSQL Database postgres: <<: *app-common image: postgres:16.1-alpine3.19 container_name: secure-mcp-postgres environment: POSTGRES_DB: mcp_db POSTGRES_USER: mcp_user POSTGRES_PASSWORD: ${DB_PASSWORD:-SecurePass123!} POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" PGDATA: /var/lib/postgresql/data/pgdata volumes: - postgres-data:/var/lib/postgresql/data:rw - ./scripts/postgres-init.sql:/docker-entrypoint-initdb.d/init.sql:ro ports: - "5432:5432" security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - SETUID - SETGID - DAC_OVERRIDE healthcheck: test: ["CMD-SHELL", "pg_isready -U mcp_user -d mcp_db"] interval: 10s timeout: 5s retries: 5 start_period: 30s command: > postgres -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c max_connections=200 -c shared_buffers=256MB -c effective_cache_size=1GB -c maintenance_work_mem=64MB -c checkpoint_completion_target=0.9 -c wal_buffers=16MB -c default_statistics_target=100 -c random_page_cost=1.1 -c effective_io_concurrency=200 -c work_mem=1310kB -c min_wal_size=1GB -c max_wal_size=4GB # Redis Cache redis: <<: *app-common image: redis:7.2.3-alpine3.19 container_name: secure-mcp-redis command: > redis-server --requirepass ${REDIS_PASSWORD:-RedisPass123!} --maxmemory 512mb --maxmemory-policy allkeys-lru --appendonly yes --appendfsync everysec --tcp-backlog 511 --tcp-keepalive 300 --timeout 0 --databases 16 --save 900 1 --save 300 10 --save 60 10000 --rdbcompression yes --rdbchecksum yes --stop-writes-on-bgsave-error yes volumes: - redis-data:/data:rw ports: - "6379:6379" security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - SETUID - SETGID healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 20s # HashiCorp Vault for secrets management vault: <<: *app-common image: hashicorp/vault:1.15.4 container_name: secure-mcp-vault environment: VAULT_DEV_ROOT_TOKEN_ID: ${VAULT_TOKEN:-development-token} VAULT_DEV_LISTEN_ADDRESS: 0.0.0.0:8200 VAULT_LOG_LEVEL: ${VAULT_LOG_LEVEL:-info} volumes: - vault-data:/vault/data:rw - vault-logs:/vault/logs:rw - ./scripts/vault-config.hcl:/vault/config/vault.hcl:ro ports: - "8200:8200" cap_drop: - ALL cap_add: - IPC_LOCK - SETUID - SETGID security_opt: - no-new-privileges:true command: server -dev # Prometheus for metrics collection prometheus: <<: *app-common image: prom/prometheus:v2.48.1 container_name: secure-mcp-prometheus volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus:rw command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' - '--storage.tsdb.retention.size=10GB' - '--web.enable-lifecycle' - '--web.enable-admin-api' ports: - "9090:9090" security_opt: - no-new-privileges:true cap_drop: - ALL # Grafana for visualization grafana: <<: *app-common image: grafana/grafana:10.2.3 container_name: secure-mcp-grafana environment: GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin} GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-GrafanaPass123!} GF_INSTALL_PLUGINS: grafana-clock-panel,grafana-simple-json-datasource GF_SERVER_ROOT_URL: ${GRAFANA_ROOT_URL:-http://localhost:3001} GF_ANALYTICS_REPORTING_ENABLED: "false" GF_ANALYTICS_CHECK_FOR_UPDATES: "false" volumes: - grafana-data:/var/lib/grafana:rw - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards:ro - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources:ro ports: - "3001:3000" depends_on: - prometheus security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - SETUID - SETGID # Jaeger for distributed tracing jaeger: <<: *app-common image: jaegertracing/all-in-one:1.53 container_name: secure-mcp-jaeger environment: COLLECTOR_OTLP_ENABLED: "true" SPAN_STORAGE_TYPE: badger BADGER_EPHEMERAL: "false" BADGER_DIRECTORY_VALUE: /badger/data BADGER_DIRECTORY_KEY: /badger/key volumes: - jaeger-data:/badger:rw ports: - "16686:16686" # Jaeger UI - "4318:4318" # OTLP HTTP - "4317:4317" # OTLP gRPC security_opt: - no-new-privileges:true cap_drop: - ALL # NGINX as reverse proxy nginx: <<: *app-common image: nginx:1.25.3-alpine3.18 container_name: secure-mcp-nginx volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - nginx-cache:/var/cache/nginx:rw - nginx-logs:/var/log/nginx:rw ports: - "80:80" - "443:443" depends_on: - app security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - SETUID - SETGID healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 volumes: app-logs: driver: local app-tmp: driver: local postgres-data: driver: local redis-data: driver: local vault-data: driver: local vault-logs: driver: local prometheus-data: driver: local grafana-data: driver: local jaeger-data: driver: local nginx-cache: driver: local nginx-logs: driver: local networks: secure-mcp: driver: bridge ipam: config: - subnet: 172.28.0.0/16 gateway: 172.28.0.1

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/perfecxion-ai/secure-mcp'

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