Docker развёртывание
Полное руководство по контейнеризации MCP серверов с Docker
Docker обеспечивает изоляцию, воспроизводимость и простоту развёртывания MCP серверов в любой среде.
Базовый Dockerfile
Заголовок раздела «Базовый Dockerfile»Python (Multi-stage)
Заголовок раздела «Python (Multi-stage)»# Build stage для зависимостейFROM python:3.12-slim AS builder
WORKDIR /app
# Установка build-зависимостейRUN apt-get update && apt-get install -y --no-install-recommends \ gcc libpq-dev && rm -rf /var/lib/apt/lists/*
# Виртуальное окружениеRUN python -m venv /opt/venvENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
# Production stageFROM python:3.12-slim
# Non-root пользовательRUN useradd --create-home --shell /bin/bash mcpWORKDIR /home/mcp/app
# Копирование venv из builderCOPY --from=builder /opt/venv /opt/venvENV PATH="/opt/venv/bin:$PATH"
# Копирование кодаCOPY --chown=mcp:mcp src/ ./src/
USER mcp
CMD ["python", "-m", "src.server"]Python (простой вариант)
Заголовок раздела «Python (простой вариант)»FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
COPY src/ ./src/
CMD ["python", "-m", "src.server"]TypeScript
Заголовок раздела «TypeScript»# Multi-stage buildFROM node:20-alpine AS builder
WORKDIR /appCOPY package*.json ./RUN npm ci
COPY . .RUN npm run build
# Production stageFROM node:20-alpine
WORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCOPY package*.json ./
CMD ["node", "dist/index.js"]FROM rust:1.75 AS builder
WORKDIR /appCOPY . .RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*COPY --from=builder /app/target/release/mcp-server /usr/local/bin/
CMD ["mcp-server"]FROM golang:1.21-alpine AS builder
WORKDIR /appCOPY go.mod go.sum ./RUN go mod download
COPY . .RUN CGO_ENABLED=0 go build -o mcp-server ./cmd/server
FROM alpine:latest
RUN apk --no-cache add ca-certificatesCOPY --from=builder /app/mcp-server /usr/local/bin/
CMD ["mcp-server"]docker-compose.yml
Заголовок раздела «docker-compose.yml»Для комплексных сервисов с зависимостями:
version: '3.8'
services: mcp-server: build: . container_name: mcp-server restart: unless-stopped volumes: - ./data:/app/data:ro - ./config:/app/config:ro environment: - DATABASE_URL=postgresql://postgres:password@db:5432/mcp - LOG_LEVEL=info depends_on: - db networks: - mcp-network
db: image: postgres:16-alpine container_name: mcp-db restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=password - POSTGRES_DB=mcp networks: - mcp-network
volumes: postgres_data:
networks: mcp-network: driver: bridgeVolume Mounting
Заголовок раздела «Volume Mounting»Для доступа к данным на хосте:
services: mcp-server: volumes: # Только чтение для безопасности - /home/user/documents:/app/documents:ro
# Запись для кэша - mcp-cache:/app/cache
# Конфигурация - ./config.json:/app/config.json:roEnvironment Variables
Заголовок раздела «Environment Variables»ENV MCP_SERVER_NAME=my-serverENV MCP_LOG_LEVEL=infoENV MCP_MAX_CONNECTIONS=100services: mcp-server: environment: - MCP_SERVER_NAME=${SERVER_NAME:-default} - MCP_LOG_LEVEL=${LOG_LEVEL:-info} - DATABASE_URL env_file: - .envSERVER_NAME=production-serverLOG_LEVEL=warnDATABASE_URL=postgresql://user:pass@host:5432/dbNetworking
Заголовок раздела «Networking»HTTP/SSE транспорт
Заголовок раздела «HTTP/SSE транспорт»services: mcp-server: ports: - "3000:3000" environment: - MCP_TRANSPORT=http - MCP_PORT=3000Internal network
Заголовок раздела «Internal network»services: mcp-server: networks: - internal
app: networks: - internal environment: - MCP_SERVER_URL=http://mcp-server:3000
networks: internal: internal: trueHealth Checks
Заголовок раздела «Health Checks»HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1services: mcp-server: healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 5sSecurity Best Practices
Заголовок раздела «Security Best Practices»Non-root user
Заголовок раздела «Non-root user»FROM python:3.12-slim
# Создание non-root пользователяRUN useradd --create-home --shell /bin/bash mcpUSER mcp
WORKDIR /home/mcp/appCOPY --chown=mcp:mcp . .
CMD ["python", "-m", "src.server"]Read-only filesystem
Заголовок раздела «Read-only filesystem»services: mcp-server: read_only: true tmpfs: - /tmp volumes: - ./data:/app/data:roCapabilities
Заголовок раздела «Capabilities»services: mcp-server: cap_drop: - ALL security_opt: - no-new-privileges:trueLogging
Заголовок раздела «Logging»services: mcp-server: logging: driver: json-file options: max-size: "10m" max-file: "3"Централизованное логирование
Заголовок раздела «Централизованное логирование»services: mcp-server: logging: driver: syslog options: syslog-address: "tcp://logs.example.com:514" tag: "mcp-server"Production Deployment
Заголовок раздела «Production Deployment»Kubernetes-ready
Заголовок раздела «Kubernetes-ready»FROM python:3.12-slim
# Labels для KubernetesLABEL org.opencontainers.image.source="https://github.com/user/mcp-server"LABEL org.opencontainers.image.version="1.0.0"
WORKDIR /app
# Сигнал для graceful shutdownSTOPSIGNAL SIGTERM
COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
COPY src/ ./src/
# Health check endpointEXPOSE 8080
USER 1000
CMD ["python", "-m", "src.server"]Kubernetes deployment
Заголовок раздела «Kubernetes deployment»apiVersion: apps/v1kind: Deploymentmetadata: name: mcp-serverspec: replicas: 3 selector: matchLabels: app: mcp-server template: metadata: labels: app: mcp-server spec: containers: - name: mcp-server image: registry.example.com/mcp-server:1.0.0 ports: - containerPort: 3000 resources: limits: memory: "256Mi" cpu: "500m" requests: memory: "128Mi" cpu: "250m" livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 3000 initialDelaySeconds: 5 periodSeconds: 10Claude Desktop с Docker
Заголовок раздела «Claude Desktop с Docker»Настройка через wrapper script
Заголовок раздела «Настройка через wrapper script»Создайте run-mcp-docker.sh:
#!/bin/bashdocker run --rm -i \ -v /home/user/data:/app/data:ro \ -e LOG_LEVEL=info \ my-mcp-server:latestClaude Desktop config
Заголовок раздела «Claude Desktop config»{ "mcpServers": { "docker-server": { "command": "/path/to/run-mcp-docker.sh" } }}Альтернативный метод
Заголовок раздела «Альтернативный метод»{ "mcpServers": { "docker-server": { "command": "docker", "args": [ "run", "--rm", "-i", "-v", "/home/user/data:/app/data:ro", "my-mcp-server:latest" ] } }}Сборка и публикация
Заголовок раздела «Сборка и публикация»# Сборкаdocker build -t my-mcp-server:1.0.0 .
# Тегирование для registrydocker tag my-mcp-server:1.0.0 registry.example.com/my-mcp-server:1.0.0
# Pushdocker push registry.example.com/my-mcp-server:1.0.0Multi-platform builds
Заголовок раздела «Multi-platform builds»# Сборка для нескольких архитектурdocker buildx build \ --platform linux/amd64,linux/arm64 \ -t my-mcp-server:1.0.0 \ --push .