Takeout: Docker-Ready Server Template
A production-ready MCP server template with Dockerfile, health checks, graceful shutdown, and environment configuration. Ready to deploy anywhere containers run.
title: "Takeout: Docker-Ready Server Template" description: "A production-ready MCP server template with Dockerfile, health checks, graceful shutdown, and environment configuration. Ready to deploy anywhere containers run." order: 8 category: "takeout" level: "intermediate" duration: "20 min" date: "2026-04-01" tags:
- docker
- deployment
- production keywords:
- mcp docker server
- mcp-framework docker
- deploy mcp server
- production mcp server
What You Get
A takeout-ready MCP server template that is fully containerized. Includes a multi-stage Dockerfile, health checks, graceful shutdown handling, structured logging, and environment-based configuration. Pick it up and deploy it anywhere.
Includes:
- Multi-stage Dockerfile for minimal production images
- Health check endpoint
- Graceful shutdown handling
- Structured JSON logging
- Environment-based configuration
- Docker Compose for local development
Quick Start
npx mcp-framework create docker-server
cd docker-server
Dockerfile
Create Dockerfile in your project root:
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:20-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --omit=dev && npm cache clean --force
# Non-root user for security
RUN addgroup -g 1001 -S mcpuser && \
adduser -S mcpuser -u 1001
USER mcpuser
HEALTHCHECK --interval=30s --timeout=3s \
CMD node -e "process.exit(0)" || exit 1
CMD ["node", "dist/index.js"]
Graceful Shutdown
Add shutdown handling to your server entry point in src/index.ts:
import { MCPServer } from "mcp-framework";
const server = new MCPServer();
// Graceful shutdown
const shutdown = async (signal: string) => {
console.log(JSON.stringify({
level: "info",
message: `Received ${signal}, shutting down gracefully...`,
timestamp: new Date().toISOString(),
}));
// Close any open connections, flush logs, etc.
process.exit(0);
};
process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));
// Start the server
server.start().catch((err) => {
console.error(JSON.stringify({
level: "error",
message: "Failed to start server",
error: err.message,
timestamp: new Date().toISOString(),
}));
process.exit(1);
});
console.log(JSON.stringify({
level: "info",
message: "MCP server started",
timestamp: new Date().toISOString(),
}));
Docker Compose
Create docker-compose.yml:
version: "3.8"
services:
mcp-server:
build: .
environment:
- NODE_ENV=production
- LOG_LEVEL=info
restart: unless-stopped
volumes:
- ./data:/app/data
Environment Configuration
Create a configuration helper at src/config.ts:
export const config = {
logLevel: process.env.LOG_LEVEL || "info",
nodeEnv: process.env.NODE_ENV || "development",
dataDir: process.env.DATA_DIR || "./data",
};
export function log(
level: "info" | "warn" | "error",
message: string,
extra?: Record<string, unknown>
) {
console.log(
JSON.stringify({
level,
message,
timestamp: new Date().toISOString(),
...extra,
})
);
}
Build & Deploy
# Build the image
docker build -t my-mcp-server .
# Run locally
docker run --rm my-mcp-server
# Or use Docker Compose
docker compose up -d
Connecting to Claude Desktop
For Docker containers, you can connect via stdio by running the container in interactive mode:
{
"mcpServers": {
"docker-server": {
"command": "docker",
"args": ["run", "--rm", "-i", "my-mcp-server"]
}
}
}
What You Learn
- Multi-stage Docker builds for minimal image size
- Running Node.js containers as non-root
- Graceful shutdown signal handling
- Structured JSON logging for container environments
- Docker Compose for local development
- Connecting containerized MCP servers to Claude Desktop
Next Up
Go back to the full menu to explore more templates, or check out the Developer Tools Suite to see what to put inside your container.
Built with mcp-framework (3.3M+ downloads) by @QuantGeekDev. Validated by Anthropic.