Docker Deployment
Relevant source files
The following files were used as context for generating this wiki page:The zen-mcp-server project utilizes Docker to provide a consistent, isolated, and secure environment for running the server. This containerized setup simplifies dependency management and ensures the server behaves identically across different host machines. The deployment can be managed either through direct docker run commands, which is the recommended approach for integration with MCP clients, or via docker-compose for development and monitoring purposes.
The Docker configuration is designed for security and persistence. It runs as a non-root user, uses a read-only filesystem with specific writable temporary directories, and manages secrets through environment variables. Persistent volumes are used for logs and configuration, ensuring that important data is not lost when the container is restarted.
Sources: docker/README.md:3-23, 73-78, run-server.ps1:51-54, 762-768
Architecture Overview
The Docker setup is defined primarily by the docker-compose.yml file, which orchestrates the main zen-mcp service. The architecture relies on a single service container, environment variables for configuration, and mounted volumes for persistent data storage.
This diagram illustrates the main components of the Docker deployment architecture.
Sources: docker-compose.yml, docker/README.md:63-78
Service Definition
The core of the deployment is the zen-mcp service. Below are its key properties as defined in docker-compose.yml.
| Property | Value | Description |
|---|---|---|
image | zen-mcp-server:latest | The Docker image to use for the container. |
container_name | zen-mcp-server | A specific name for the container instance. |
user | zenuser | The non-root user the container process runs as. |
working_dir | /app | The working directory inside the container. |
tty | true | Allocates a pseudo-TTY. |
stdin_open | true | Keeps STDIN open, necessary for stdio communication. |
restart | unless-stopped | The container will restart unless it is explicitly stopped. |
volumes | See Volumes | Defines data persistence and host synchronization. |
healthcheck | See Health Monitoring | Defines how to determine if the container is healthy. |
Sources: docker-compose.yml:5-29
Configuration
Server configuration is managed via an .env file located in the project root. This file is not committed to version control and must be created from the provided .env.example template. At least one API key is required for the server to function.
Sources: docker/README.md:10-15, docker/scripts/deploy.sh:13-26
Environment Variables
The following table lists key environment variables used to configure the server.
| Variable | Description | Default/Example |
|---|---|---|
GEMINI_API_KEY | API key for Google Gemini models. | your_gemini_key_here |
OPENAI_API_KEY | API key for OpenAI models. | your_openai_key_here |
XAI_API_KEY | API key for xAI (Grok) models. | your_xai_key_here |
LOG_LEVEL | Sets the logging verbosity. | INFO |
DEFAULT_MODEL | The default model to use if not specified. | auto |
DEFAULT_THINKING_MODE_THINKDEEP | Default thinking mode for the thinkdeep tool. | high |
Sources: docker/README.md:180-193, docker/scripts/deploy.sh:13-20
Build Process
The Docker image zen-mcp-server:latest is built using a Dockerfile in the root directory. The project provides helper scripts to simplify this process. The build process uses a multi-stage build to create an optimized and smaller final image.
Sources: docker/README.md:17-27, 218-219, docker/scripts/build.sh
This flowchart shows the steps involved in building the Docker image using the build.sh script.
Sources: docker/scripts/build.sh:10-25
You can build the image using one of the provided scripts:
Bash:
# Make the script executable
chmod +x docker/scripts/build.sh
# Run the build script
./docker/scripts/build.sh
Sources: docker/README.md:21-23
PowerShell:
# Run the PowerShell build script
docker/scripts/build.ps1
Sources: docker/README.md:25-26
The PowerShell script run-server.ps1 also includes logic to build the Docker image if the -Docker flag is used, and it can be forced to rebuild with -Force.
Sources: run-server.ps1:785-827
Deployment and Usage
There are two primary methods for running the server in a Docker container.
A. Direct docker run
This is the recommended method for integrating with an MCP client like Claude Desktop. It runs a new, ephemeral container for each command.
docker run --rm -i --env-file .env \
-v $(pwd)/logs:/app/logs \
zen-mcp-server:latest
Sources: docker/README.md:32-35
B. Docker Compose
Using Docker Compose is ideal for development, testing, or long-running server instances. The project provides scripts to manage the deployment.
Deployment Script Flow (deploy.sh)
This sequence diagram shows how the deploy.sh script works.
Sources: docker/scripts/deploy.sh
To deploy using the scripts:
Bash:
# Make the script executable
chmod +x docker/scripts/deploy.sh
# Run the deploy script
./docker/scripts/deploy.sh
Sources: docker/README.md:41-43
PowerShell:
The run-server.ps1 script orchestrates the Docker Compose deployment when run with the -Docker flag.
.\run-server.ps1 -Docker
Sources: run-server.ps1:762-783, 1146-1168.
Volumes and Persistent Data
To ensure data persistence across container restarts, the Docker setup uses both named volumes and host-mounted directories.
| Volume Mount | Type | Description |
|---|---|---|
./logs:/app/logs | Host Mount | Persists server logs to a logs directory on the host machine. |
zen-mcp-config:/app/conf | Named Volume | Persists configuration data stored in /app/conf inside the container. |
/etc/localtime:/etc/localtime:ro | Host Mount | Synchronizes the container's timezone with the host's timezone (read-only). |
Sources: docker-compose.yml:19-22, docker/README.md:63-78
The named volume zen-mcp-config is defined at the top level of the docker-compose.yml file.
volumes:
zen-mcp-config:
driver: local
Sources: docker-compose.yml:31-33
Health Monitoring
The zen-mcp service includes a health check to verify its operational status. The check runs a script inside the container every 30 seconds after an initial 60-second startup period.
The health check verifies:
- The server process is running.
- Python modules can be imported.
- The log directory is writable.
- API keys are configured.
Sources: docker-compose.yml:24-29, docker/README.md:56-61
The deploy.sh script actively waits for the container to become healthy before completing.
Sources: docker/scripts/deploy.sh:49-65
Security
The Docker environment is configured with several security best practices:
- Non-Root User: The container runs as
zenuserto limit privileges. - Read-Only Filesystem: The root filesystem is read-only, with temporary file systems (
tmpfs) for writable locations like/tmp. - No Exposed Ports: Communication occurs over
stdio, so no network ports are exposed. - Secrets Management: API keys and other secrets are passed via environment variables, typically from a local
.envfile, which is not committed to source control.
Sources: docker-compose.yml:10, 16-17, docker/README.md:73-78
Client Integration
To connect an MCP client, you configure it to execute a docker command. The recommended configuration uses docker run to ensure a clean, ephemeral environment for each interaction.
Example for Claude Desktop:
{
"servers": {
"zen-docker": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--env-file",
"/absolute/path/to/zen-mcp-server/.env",
"-v",
"/absolute/path/to/zen-mcp-server/logs:/app/logs",
"zen-mcp-server:latest"
]
}
}
}
Sources: docker/README.md:227-243
The run-server.ps1 script can also automatically configure various clients (like VSCode, Cursor, etc.) to use the correct Docker command.
Sources: run-server.ps1:829-1144