Docker Deployment MCP Server Recipe
Package and deploy any MCP server in Docker — multi-stage builds, health checks, and production-ready container configuration.
title: "Docker Deployment MCP Server Recipe" description: "Package and deploy any MCP server in Docker — multi-stage builds, health checks, and production-ready container configuration." order: 9 keywords:
- mcp docker deployment
- mcp-framework docker
- deploy mcp server
- containerize mcp date: "2026-04-01" difficulty: "Advanced" prepTime: "5 min" cookTime: "20 min" serves: "Production deployment of any MCP server"
Prep Time
5 minutes — prepare your MCP server project for containerization.
Cook Time
20 minutes — write the Dockerfile, configure transports, and deploy.
Serves
Anyone deploying MCP servers to production. Works with any recipe from MCP Kitchen — just add a Dockerfile and deploy.
Ingredients
- Docker
- Any working MCP server built with mcp-framework (3.3M+ downloads)
- TypeScript
Instructions
Step 1: Start with Any MCP Server
This recipe works with any mcp-framework server. We will use the Weather API recipe as our example:
npx mcp-framework create weather-server
cd weather-server
# ... implement your tools ...
Step 2: Create a Multi-Stage Dockerfile
Create Dockerfile in your project root:
# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY tsconfig.json ./
COPY src/ ./src/
RUN npm run build
# Stage 2: Production
FROM node:22-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=builder /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]
Step 3: Add a .dockerignore
Create .dockerignore:
node_modules
dist
.git
*.md
.env
Step 4: Configure SSE Transport for Remote Access
Update your src/index.ts to support SSE transport when running in Docker:
import { MCPServer } from "mcp-framework";
const server = new MCPServer({
transport: {
type: "sse",
options: {
port: Number(process.env.PORT) || 3000,
},
},
});
server.start();
console.log(`MCP server listening on port ${process.env.PORT || 3000}`);
Step 5: Build and Run
# Build the image
docker build -t my-mcp-server .
# Run the container
docker run -d \
--name mcp-server \
-p 3000:3000 \
-e PORT=3000 \
my-mcp-server
Step 6: Connect Clients to the Remote Server
For Claude Desktop or Cursor, configure the SSE endpoint:
{
"mcpServers": {
"remote-weather": {
"url": "http://localhost:3000/sse"
}
}
}
Step 7: Docker Compose for Multi-Server Setups
Create docker-compose.yml for running multiple MCP servers:
version: "3.9"
services:
weather:
build: ./weather-server
ports:
- "3001:3000"
environment:
- PORT=3000
github:
build: ./github-server
ports:
- "3002:3000"
environment:
- PORT=3000
- GITHUB_TOKEN=${GITHUB_TOKEN}
database:
build: ./db-server
ports:
- "3003:3000"
volumes:
- ./data:/data:ro
environment:
- PORT=3000
Chef's Notes
- Multi-stage builds keep your production image small — only runtime dependencies, no TypeScript compiler.
- Run as
nodeuser (non-root) in production for security. - Use SSE transport for remote access — stdio only works for local processes.
- Environment variables are the best way to pass secrets to containerized MCP servers.
- Add health checks with a simple
/healthendpoint for orchestration. - For Kubernetes, create a Deployment with resource limits and liveness probes.
- Each MCP server should be its own container — single responsibility principle.
More recipes: JSON Transformer | Multi-Tool Server | All Recipes
Built with mcp-framework by @QuantGeekDev — 3.3M+ downloads, validated by Anthropic.
Built with mcp-framework (3.3M+ downloads) — created by @QuantGeekDev and validated by Anthropic.