Overview
Docker deployment provides a containerized, production-ready environment for the Secure MCP Gateway. The included Docker Compose stack bundles the gateway with a complete observability platform.
Prerequisites
Docker : 20.10 or higher
Docker Compose : v2.0 or higher
Git (for cloning the repository)
Verify Docker Installation
# Check Docker version
docker --version
# Expected: Docker version 20.10.0 or higher
# Check Docker Compose version
docker compose version
# Expected: Docker Compose version v2.0.0 or higher
# Verify Docker is running
docker ps
Quick Start
Build Docker Image
Build the gateway image from the repository: # Clone repository (if not already done)
git clone https://github.com/enkryptai/secure-mcp-gateway
cd secure-mcp-gateway
# Build image
docker build -t secure-mcp-gateway .
Build time: ~2-5 minutes depending on your machine. The image includes Python 3.12, Node.js 22.x, and all gateway dependencies.
Generate Configuration
Generate the Docker-specific config file: macOS/Linux
Windows (CMD)
Windows (PowerShell)
docker run --rm \
-e HOST_OS=macos \
-e HOST_ENKRYPT_HOME= $HOME /.enkrypt \
-v ~/.enkrypt/docker:/app/.enkrypt/docker \
--entrypoint python \
secure-mcp-gateway \
-m secure_mcp_gateway.cli generate-config
This creates:
macOS/Linux : ~/.enkrypt/docker/enkrypt_mcp_config.json
Windows : %USERPROFILE%\.enkrypt\docker\enkrypt_mcp_config.json
Install for Claude Desktop
Register the Docker gateway with Claude Desktop: macOS/Linux
Windows (CMD)
Windows (PowerShell)
docker run --rm -i \
-e HOST_OS=macos \
-e HOST_ENKRYPT_HOME= $HOME /.enkrypt \
-v ~/.enkrypt/docker:/app/.enkrypt/docker \
-v ~/Library/Application \ Support/Claude:/app/.claude \
--entrypoint python \
secure-mcp-gateway \
-m secure_mcp_gateway.cli install --client claude-desktop
Important : The generated config includes MCP_TRANSPORT=stdio for stdio mode communication. Restart Claude Desktop after installation.
Run Gateway Container
Start the gateway in detached mode: docker run -d \
--name secure-mcp-gateway \
-p 8000:8000 \
-v ~/.enkrypt/docker:/app/.enkrypt/docker \
-e ENKRYPT_GATEWAY_KEY="<your_gateway_key>" \
-e ENKRYPT_PROJECT_ID="<your_project_id>" \
-e ENKRYPT_USER_ID="<your_user_id>" \
secure-mcp-gateway
Replace <your_gateway_key>, <your_project_id>, and <your_user_id> with values from your generated config file.
Docker Compose Deployment
For production deployments, use Docker Compose to deploy the gateway with the complete observability stack.
Observability Stack Components
The infra/docker-compose.yml includes:
OpenTelemetry Collector Receives OTLP traces, metrics, and logs from gateway
Jaeger Distributed tracing visualization (port 16686)
Loki Log aggregation and storage (port 3100)
Prometheus Metrics storage and querying (port 9090)
Grafana Unified dashboards for metrics, logs, traces (port 3000)
Docker Compose Configuration
name : secure-mcp-gateway-infra
services :
# OpenTelemetry Collector - Central telemetry hub
otel-collector :
image : otel/opentelemetry-collector-contrib:0.134.1
command : [ "--config=/etc/otel-collector-config.yaml" ]
volumes :
- ./otel_collector/otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports :
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
- "8889:8889" # Prometheus metrics exporter
depends_on :
- jaeger
- loki
# Jaeger - Distributed tracing
jaeger :
image : jaegertracing/all-in-one:1.73.0
ports :
- "16686:16686" # Web UI
- "14250:14250" # gRPC collector endpoint
- "16685:16685" # Query port for Grafana
environment :
- LOG_LEVEL=debug
- QUERY_BASE_PATH=/jaeger
- COLLECTOR_OTLP_ENABLED=true
# Loki - Log aggregation
loki :
image : grafana/loki:main-cadc824
ports :
- "3100:3100"
volumes :
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
command : -config.file=/etc/loki/local-config.yaml
# Prometheus - Metrics storage
prometheus :
image : prom/prometheus:v3.5.0
ports :
- "9090:9090"
volumes :
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
command :
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
depends_on :
- otel-collector
# Grafana - Visualization
grafana :
image : grafana/grafana:12.2.0-17535958692
ports :
- "3000:3000"
environment :
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
volumes :
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on :
- loki
- otel-collector
- prometheus
Prometheus Configuration
infra/prometheus/prometheus.yml
global :
scrape_interval : 15s
evaluation_interval : 15s
scrape_configs :
- job_name : 'otel-collector'
static_configs :
- targets : [ 'otel-collector:8889' ]
Launch Observability Stack
# Navigate to infrastructure directory
cd infra
# Start all services
docker compose up -d
# Check service status
docker compose ps
# View logs
docker compose logs -f
# Stop services
docker compose down
Access Dashboards
Once the stack is running:
Grafana URL : http://localhost:3000 Auth : Anonymous (Admin role)View unified dashboards with metrics, logs, and traces
Dockerfile Breakdown
The gateway Dockerfile is a multi-runtime environment:
# Base: Ubuntu 24.04 LTS for stability
FROM ubuntu:24.04
WORKDIR /app
# Install system dependencies:
# - Python 3.12 (pip, uv, pipx)
# - Node.js 22.x LTS (npm, npx)
# - Build tools (gcc, g++, make)
# - Utilities (git, jq, yq, curl, ssh)
RUN apt-get update && apt-get install -y \
python3.12 python3.12-dev python3-pip \
build-essential gcc g++ make \
nodejs npm curl wget git jq yq \
openssh-client unzip zip tar \
&& rm -rf /var/lib/apt/lists/*
# Set Python 3.12 as default
RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
# Install uv (fast Python package installer)
RUN pip3 install --break-system-packages uv
# Install Node.js LTS (22.x)
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm@latest
# Copy and install Python dependencies
COPY requirements.txt requirements-dev.txt ./
RUN pip3 install --break-system-packages --upgrade pip setuptools wheel \
&& pip3 install --break-system-packages -r requirements.txt \
&& pip3 install --break-system-packages -r requirements-dev.txt
# Copy source code and metadata
COPY src src
COPY setup.py MANIFEST.in pyproject.toml ./
COPY CHANGELOG.md LICENSE.txt README.md README_PYPI.md ./
# Configure for ingress
ENV HOST=0.0.0.0
ENV FASTAPI_HOST=0.0.0.0
# Build and install package
RUN python3 -m build && pip3 install --break-system-packages .
EXPOSE 8000
# Entrypoint: Run gateway server
ENTRYPOST [ "python3" , "src/secure_mcp_gateway/gateway.py" ]
Image Features
pip : Standard package installer
uv : Fast Rust-based package installer (10-100x faster)
pipx : Isolated Python app installations
Supports Python-based MCP servers
npm : Package manager
npx : Package executor
Supports JavaScript/TypeScript MCP servers (e.g., GitHub MCP)
Git : Repository operations
jq/yq : JSON/YAML processing
curl/wget : HTTP downloads
ssh : Secure remote access
zip/tar : Archive handling
Claude Desktop Configuration
After Docker installation, your Claude config will look like:
claude_desktop_config.json
{
"mcpServers" : {
"Enkrypt Secure MCP Gateway" : {
"command" : "docker" ,
"args" : [
"run" ,
"--rm" ,
"-i" ,
"-e" ,
"MCP_TRANSPORT=stdio" ,
"-v" ,
"/Users/user/.enkrypt/docker:/app/.enkrypt/docker" ,
"secure-mcp-gateway"
],
"env" : {
"ENKRYPT_GATEWAY_KEY" : "2W8UupCkazk4SsOcSu_..." ,
"ENKRYPT_PROJECT_ID" : "3c09f06c-..." ,
"ENKRYPT_USER_ID" : "6469a670-..."
}
}
}
}
The MCP_TRANSPORT=stdio environment variable enables stdio communication mode for Claude Desktop integration.
Environment Variables
Key environment variables for Docker deployment:
Variable Description Default HOSTGateway bind address 0.0.0.0FASTAPI_HOSTFastAPI server bind address 0.0.0.0ENKRYPT_GATEWAY_KEYAPI key for authentication (from config) ENKRYPT_PROJECT_IDProject identifier (from config) ENKRYPT_USER_IDUser identifier (from config) MCP_TRANSPORTMCP communication mode stdioDEBIAN_FRONTENDPrevent interactive prompts noninteractive
Volumes
Mount these volumes for persistence:
# Configuration directory
-v ~/.enkrypt/docker:/app/.enkrypt/docker
# Logs directory (optional)
-v ~/.enkrypt/logs:/app/.enkrypt/logs
# Custom MCP servers (optional)
-v ~/mcp-servers:/app/mcp-servers
Networking
Exposed Ports
8000 : Gateway MCP server (streamable HTTP)
8001 : FastAPI REST API (if enabled)
Docker Network
The Compose stack creates a bridge network for inter-service communication:
# View network
docker network inspect secure-mcp-gateway-infra_default
# Services can reference each other by name:
# - otel-collector:4317
# - prometheus:9090
# - jaeger:16686
Health Checks
# Check gateway health
curl http://localhost:8000/health
# Check OpenTelemetry Collector
curl http://localhost:8889/metrics
# Check Prometheus targets
curl http://localhost:9090/api/v1/targets
# Check Loki ready
curl http://localhost:3100/ready
Monitoring Gateway Logs
# Follow gateway logs
docker logs -f secure-mcp-gateway
# View last 100 lines
docker logs --tail 100 secure-mcp-gateway
# View logs with timestamps
docker logs -t secure-mcp-gateway
# View all services (Compose)
docker compose logs -f
Troubleshooting
Container Won’t Start
# Check container logs
docker logs secure-mcp-gateway
# Inspect container
docker inspect secure-mcp-gateway
# Verify image built correctly
docker images | grep secure-mcp-gateway
Port Conflicts
# Check if ports are in use
lsof -i :8000
lsof -i :3000
# Change port mapping
docker run -p 8080:8000 ...
Volume Permissions
# macOS/Linux - Fix permissions
chmod -R 755 ~/.enkrypt/docker
# Check volume mounts
docker inspect secure-mcp-gateway | grep Mounts -A 10
Observability Stack Issues
# Restart services
docker compose restart
# Rebuild services
docker compose up -d --build
# Check service health
docker compose ps
# View specific service logs
docker compose logs grafana
docker compose logs otel-collector
Updating
# Pull latest code
git pull origin main
# Rebuild image
docker build -t secure-mcp-gateway .
# Stop old container
docker stop secure-mcp-gateway
docker rm secure-mcp-gateway
# Start new container
docker run -d ...
# Or with Compose
docker compose down
docker compose up -d --build
Production Considerations
Security Notes :
Docker-in-Docker (DinD) is commented out in the Dockerfile for security reasons
Only enable DinD if you understand the security implications
Use secrets management for API keys in production
Enable TLS for OTLP endpoints
Use External Cache Deploy Redis/KeyDB for distributed caching across multiple gateway instances
Enable TLS Configure TLS certificates for secure communication with OTLP collector
Resource Limits Set memory and CPU limits: docker run --memory= "2g" --cpus= "1.5" ...
Persistent Storage Use named volumes for Prometheus, Loki, and Grafana data persistence
Next Steps
Deployment Patterns Learn about production deployment architectures
External Cache Setup Configure Redis/KeyDB for distributed caching
Monitoring Guide Deep dive into metrics, traces, and logs
CLI Commands Manage Docker deployment with CLI