feat: add timezone synchronization volume and update deployment scripts for health checks
Update the Docker README and create a Docker Deployment guide in the docs folder
This commit is contained in:
@@ -52,6 +52,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./logs:/app/logs
|
- ./logs:/app/logs
|
||||||
- zen-mcp-config:/app/conf
|
- zen-mcp-config:/app/conf
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
|
||||||
# Network configuration
|
# Network configuration
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -112,10 +112,34 @@ The container includes health checks that verify:
|
|||||||
- Log directory is writable
|
- Log directory is writable
|
||||||
- API keys are configured
|
- API keys are configured
|
||||||
|
|
||||||
## Volumes
|
## Volumes and Persistent Data
|
||||||
|
|
||||||
- `./logs:/app/logs` - Persistent log storage
|
The Docker setup includes persistent volumes to preserve data between container runs:
|
||||||
- `zen-mcp-config:/app/conf` - Configuration persistence
|
|
||||||
|
- **`./logs:/app/logs`** - Persistent log storage (local folder mount)
|
||||||
|
- **`zen-mcp-config:/app/conf`** - Configuration persistence (named Docker volume)
|
||||||
|
- **`/etc/localtime:/etc/localtime:ro`** - Host timezone synchronization (read-only)
|
||||||
|
|
||||||
|
### How Persistent Volumes Work
|
||||||
|
|
||||||
|
The `zen-mcp` service (used by `zen-docker-compose` and Docker Compose commands) mounts the named volume `zen-mcp-config` persistently. All data placed in `/app/conf` inside the container is preserved between runs thanks to this Docker volume.
|
||||||
|
|
||||||
|
In the `docker-compose.yml` file, you will find:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/logs
|
||||||
|
- zen-mcp-config:/app/conf
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
```
|
||||||
|
|
||||||
|
and the named volume definition:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
zen-mcp-config:
|
||||||
|
driver: local
|
||||||
|
```
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
@@ -189,9 +213,7 @@ docker run --rm -i --env-file .env zen-mcp-server:latest 2>&1 | tee docker.log
|
|||||||
|
|
||||||
## MCP Integration (Claude Desktop)
|
## MCP Integration (Claude Desktop)
|
||||||
|
|
||||||
### Configuration File Setup
|
### Recommended Configuration (docker run)
|
||||||
|
|
||||||
Add to your Claude Desktop MCP configuration:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -206,21 +228,14 @@ Add to your Claude Desktop MCP configuration:
|
|||||||
"/absolute/path/to/zen-mcp-server/.env",
|
"/absolute/path/to/zen-mcp-server/.env",
|
||||||
"-v",
|
"-v",
|
||||||
"/absolute/path/to/zen-mcp-server/logs:/app/logs",
|
"/absolute/path/to/zen-mcp-server/logs:/app/logs",
|
||||||
"zen-mcp-server:latest",
|
"zen-mcp-server:latest"
|
||||||
"python",
|
]
|
||||||
"server.py"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"DOCKER_BUILDKIT": "1"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows MCP Configuration
|
### Windows Example
|
||||||
|
|
||||||
For Windows users, use forward slashes in paths:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -235,13 +250,27 @@ For Windows users, use forward slashes in paths:
|
|||||||
"C:/Users/YourName/path/to/zen-mcp-server/.env",
|
"C:/Users/YourName/path/to/zen-mcp-server/.env",
|
||||||
"-v",
|
"-v",
|
||||||
"C:/Users/YourName/path/to/zen-mcp-server/logs:/app/logs",
|
"C:/Users/YourName/path/to/zen-mcp-server/logs:/app/logs",
|
||||||
"zen-mcp-server:latest",
|
"zen-mcp-server:latest"
|
||||||
"python",
|
]
|
||||||
"server.py"
|
}
|
||||||
],
|
}
|
||||||
"env": {
|
}
|
||||||
"DOCKER_BUILDKIT": "1"
|
```
|
||||||
}
|
|
||||||
|
### Advanced Option: docker-compose run (uses compose configuration)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"servers": {
|
||||||
|
"zen-docker": {
|
||||||
|
"command": "docker-compose",
|
||||||
|
"args": [
|
||||||
|
"-f",
|
||||||
|
"/absolute/path/to/zen-mcp-server/docker-compose.yml",
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"zen-mcp"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +278,7 @@ For Windows users, use forward slashes in paths:
|
|||||||
|
|
||||||
### Environment File Template
|
### Environment File Template
|
||||||
|
|
||||||
Create `.env` file with at least one API key:
|
Create a `.env` file with at least one API key:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Required: At least one API key
|
# Required: At least one API key
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ try {
|
|||||||
if (!$SkipHealthCheck) {
|
if (!$SkipHealthCheck) {
|
||||||
Write-ColorText "Waiting for service to be healthy..." -Color Green
|
Write-ColorText "Waiting for service to be healthy..." -Color Green
|
||||||
|
|
||||||
# Simple timeout approach for health check
|
# Try simple timeout first, then use exponential backoff if needed
|
||||||
$timeout = $HealthCheckTimeout
|
$timeout = $HealthCheckTimeout
|
||||||
$elapsed = 0
|
$elapsed = 0
|
||||||
$healthy = $false
|
$healthy = $false
|
||||||
@@ -182,10 +182,13 @@ if (!$SkipHealthCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$healthy) {
|
if (!$healthy) {
|
||||||
Write-ColorText "Service failed to become healthy within timeout" -Color Red
|
# Use exponential backoff retry mechanism
|
||||||
Write-ColorText "Checking logs:" -Color Yellow
|
if (!(Wait-ForHealth)) {
|
||||||
docker-compose logs zen-mcp
|
Write-ColorText "Service failed to become healthy" -Color Red
|
||||||
exit 1
|
Write-ColorText "Checking logs:" -Color Yellow
|
||||||
|
docker-compose logs zen-mcp
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ docker-compose up -d
|
|||||||
# Wait for health check
|
# Wait for health check
|
||||||
echo -e "${GREEN}Waiting for service to be healthy...${NC}"
|
echo -e "${GREEN}Waiting for service to be healthy...${NC}"
|
||||||
timeout 60 bash -c 'while [[ "$(docker-compose ps -q zen-mcp | xargs docker inspect -f "{{.State.Health.Status}}")" != "healthy" ]]; do sleep 2; done' || {
|
timeout 60 bash -c 'while [[ "$(docker-compose ps -q zen-mcp | xargs docker inspect -f "{{.State.Health.Status}}")" != "healthy" ]]; do sleep 2; done' || {
|
||||||
|
wait_for_health
|
||||||
echo -e "${RED}Service failed to become healthy${NC}"
|
echo -e "${RED}Service failed to become healthy${NC}"
|
||||||
echo -e "${YELLOW}Checking logs:${NC}"
|
echo -e "${YELLOW}Checking logs:${NC}"
|
||||||
docker-compose logs zen-mcp
|
docker-compose logs zen-mcp
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import openai
|
|
||||||
|
|
||||||
|
|
||||||
def check_process():
|
def check_process():
|
||||||
"""Check if the main server process is running"""
|
"""Check if the main server process is running"""
|
||||||
@@ -78,33 +76,6 @@ def check_environment():
|
|||||||
print(f"API key {key} appears too short or invalid", file=sys.stderr)
|
print(f"API key {key} appears too short or invalid", file=sys.stderr)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Optionally, try a minimal connectivity check for OpenAI and Google Gemini
|
|
||||||
# (only if their API keys are present)
|
|
||||||
try:
|
|
||||||
if os.getenv("OPENAI_API_KEY"):
|
|
||||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
|
||||||
try:
|
|
||||||
openai.Model.list()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"OpenAI connectivity check failed: {e}", file=sys.stderr)
|
|
||||||
return False
|
|
||||||
except ImportError:
|
|
||||||
pass # Already checked in check_python_imports
|
|
||||||
|
|
||||||
try:
|
|
||||||
if os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY"):
|
|
||||||
import google.genai as genai
|
|
||||||
|
|
||||||
key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")
|
|
||||||
genai.configure(api_key=key)
|
|
||||||
try:
|
|
||||||
genai.list_models()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Google Gemini connectivity check failed: {e}", file=sys.stderr)
|
|
||||||
return False
|
|
||||||
except ImportError:
|
|
||||||
pass # Already checked in check_python_imports
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
500
docs/docker-deployment.md
Normal file
500
docs/docker-deployment.md
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
# Docker Deployment Guide
|
||||||
|
|
||||||
|
This guide covers deploying Zen MCP Server using Docker and Docker Compose for production environments.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. **Clone the repository**:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/BeehiveInnovations/zen-mcp-server.git
|
||||||
|
cd zen-mcp-server
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure environment variables**:
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your API keys
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Deploy with Docker Compose**:
|
||||||
|
```bash
|
||||||
|
# Linux/macOS
|
||||||
|
./docker/scripts/deploy.sh
|
||||||
|
|
||||||
|
# Windows PowerShell
|
||||||
|
.\docker\scripts\deploy.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Configuration
|
||||||
|
|
||||||
|
### Required API Keys
|
||||||
|
|
||||||
|
At least one API key must be configured in your `.env` file:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Google Gemini (Recommended)
|
||||||
|
GEMINI_API_KEY=your_gemini_api_key_here
|
||||||
|
|
||||||
|
# OpenAI
|
||||||
|
OPENAI_API_KEY=your_openai_api_key_here
|
||||||
|
|
||||||
|
# X.AI GROK
|
||||||
|
XAI_API_KEY=your_xai_api_key_here
|
||||||
|
|
||||||
|
# OpenRouter (unified access)
|
||||||
|
OPENROUTER_API_KEY=your_openrouter_api_key_here
|
||||||
|
|
||||||
|
# Additional providers
|
||||||
|
DIAL_API_KEY=your_dial_api_key_here
|
||||||
|
DIAL_API_HOST=your_dial_host
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional Configuration
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Default model selection
|
||||||
|
DEFAULT_MODEL=auto
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
LOG_MAX_SIZE=10MB
|
||||||
|
LOG_BACKUP_COUNT=5
|
||||||
|
|
||||||
|
# Advanced settings
|
||||||
|
DEFAULT_THINKING_MODE_THINKDEEP=high
|
||||||
|
DISABLED_TOOLS=
|
||||||
|
MAX_MCP_OUTPUT_TOKENS=
|
||||||
|
|
||||||
|
# Timezone
|
||||||
|
TZ=UTC
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Scripts
|
||||||
|
|
||||||
|
### Linux/macOS Deployment
|
||||||
|
|
||||||
|
Use the provided bash script for robust deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./docker/scripts/deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- ✅ Environment validation
|
||||||
|
- ✅ Exponential backoff health checks
|
||||||
|
- ✅ Automatic log management
|
||||||
|
- ✅ Service status monitoring
|
||||||
|
|
||||||
|
### Windows PowerShell Deployment
|
||||||
|
|
||||||
|
Use the PowerShell script for Windows environments:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\docker\scripts\deploy.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
**Additional Options:**
|
||||||
|
```powershell
|
||||||
|
# Skip health check
|
||||||
|
.\docker\scripts\deploy.ps1 -SkipHealthCheck
|
||||||
|
|
||||||
|
# Custom timeout
|
||||||
|
.\docker\scripts\deploy.ps1 -HealthCheckTimeout 120
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Architecture
|
||||||
|
|
||||||
|
### Multi-Stage Build
|
||||||
|
|
||||||
|
The Dockerfile uses a multi-stage build for optimal image size:
|
||||||
|
|
||||||
|
1. **Builder Stage**: Installs dependencies and creates virtual environment
|
||||||
|
2. **Runtime Stage**: Copies only necessary files for minimal footprint
|
||||||
|
|
||||||
|
### Security Features
|
||||||
|
|
||||||
|
- **Non-root user**: Runs as `zenuser` (UID/GID 1000)
|
||||||
|
- **Read-only filesystem**: Container filesystem is immutable
|
||||||
|
- **No new privileges**: Prevents privilege escalation
|
||||||
|
- **Secure tmpfs**: Temporary directories with strict permissions
|
||||||
|
|
||||||
|
### Resource Management
|
||||||
|
|
||||||
|
Default resource limits:
|
||||||
|
```yaml
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
cpus: '0.5'
|
||||||
|
reservations:
|
||||||
|
memory: 256M
|
||||||
|
cpus: '0.25'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Service Management
|
||||||
|
|
||||||
|
### Starting the Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start in background
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Start with logs
|
||||||
|
docker-compose up
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View service status
|
||||||
|
docker-compose ps
|
||||||
|
|
||||||
|
# Follow logs
|
||||||
|
docker-compose logs -f zen-mcp
|
||||||
|
|
||||||
|
# View health status
|
||||||
|
docker inspect zen-mcp-server --format='{{.State.Health.Status}}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stopping the Service
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Graceful stop
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Force stop
|
||||||
|
docker-compose down --timeout 10
|
||||||
|
```
|
||||||
|
|
||||||
|
## Health Checks
|
||||||
|
|
||||||
|
The container includes comprehensive health checks:
|
||||||
|
|
||||||
|
- **Process check**: Verifies server.py is running
|
||||||
|
- **Import check**: Validates critical Python modules
|
||||||
|
- **Directory check**: Ensures log directory is writable
|
||||||
|
- **API check**: Tests provider connectivity
|
||||||
|
|
||||||
|
Health check configuration:
|
||||||
|
```yaml
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "/usr/local/bin/healthcheck.py"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Persistent Data
|
||||||
|
|
||||||
|
### Volumes
|
||||||
|
|
||||||
|
- **Logs**: `./logs:/app/logs` - Application logs
|
||||||
|
- **Config**: `zen-mcp-config:/app/conf` - Configuration persistence
|
||||||
|
- **Time sync**: `/etc/localtime:/etc/localtime:ro` - Host timezone sync
|
||||||
|
|
||||||
|
**Note:** The `zen-mcp-config` is a named Docker volume that persists configuration data between container restarts. All data placed in `/app/conf` inside the container is preserved thanks to this persistent volume. This applies to both `docker-compose run` and `docker-compose up` commands.
|
||||||
|
|
||||||
|
### Log Management
|
||||||
|
|
||||||
|
Logs are automatically rotated with configurable retention:
|
||||||
|
|
||||||
|
```env
|
||||||
|
LOG_MAX_SIZE=10MB # Maximum log file size
|
||||||
|
LOG_BACKUP_COUNT=5 # Number of backup files to keep
|
||||||
|
```
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
### Default Configuration
|
||||||
|
|
||||||
|
- **Network**: `zen-network` (bridge)
|
||||||
|
- **Subnet**: `172.20.0.0/16`
|
||||||
|
- **Isolation**: Container runs in isolated network
|
||||||
|
|
||||||
|
### Port Exposure
|
||||||
|
|
||||||
|
By default, no ports are exposed. The MCP server communicates via stdio when used with Claude Desktop or other MCP clients.
|
||||||
|
|
||||||
|
For external access (advanced users):
|
||||||
|
```yaml
|
||||||
|
ports:
|
||||||
|
- "3000:3000" # Add to service configuration if needed
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
**1. Health check failures:**
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
docker-compose logs zen-mcp
|
||||||
|
|
||||||
|
# Manual health check
|
||||||
|
docker exec zen-mcp-server python /usr/local/bin/healthcheck.py
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Permission errors:**
|
||||||
|
```bash
|
||||||
|
# Fix log directory permissions
|
||||||
|
sudo chown -R 1000:1000 ./logs
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Environment variables not loaded:**
|
||||||
|
```bash
|
||||||
|
# Verify .env file exists and is readable
|
||||||
|
ls -la .env
|
||||||
|
cat .env
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. API key validation errors:**
|
||||||
|
```bash
|
||||||
|
# Check environment variables in container
|
||||||
|
docker exec zen-mcp-server env | grep -E "(GEMINI|OPENAI|XAI)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debug Mode
|
||||||
|
|
||||||
|
Enable verbose logging for troubleshooting:
|
||||||
|
|
||||||
|
```env
|
||||||
|
LOG_LEVEL=DEBUG
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Considerations
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
1. **Use Docker secrets** for API keys in production:
|
||||||
|
```yaml
|
||||||
|
secrets:
|
||||||
|
gemini_api_key:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Enable AppArmor/SELinux** if available
|
||||||
|
|
||||||
|
3. **Regular security updates**:
|
||||||
|
```bash
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
|
||||||
|
Consider integrating with monitoring solutions:
|
||||||
|
|
||||||
|
- **Prometheus**: Health check metrics
|
||||||
|
- **Grafana**: Log visualization
|
||||||
|
- **AlertManager**: Health status alerts
|
||||||
|
|
||||||
|
### Backup
|
||||||
|
|
||||||
|
Backup persistent volumes:
|
||||||
|
```bash
|
||||||
|
# Backup configuration
|
||||||
|
docker run --rm -v zen-mcp-config:/data -v $(pwd):/backup alpine tar czf /backup/config-backup.tar.gz -C /data .
|
||||||
|
|
||||||
|
# Restore configuration
|
||||||
|
docker run --rm -v zen-mcp-config:/data -v $(pwd):/backup alpine tar xzf /backup/config-backup.tar.gz -C /data
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Tuning
|
||||||
|
|
||||||
|
### Resource Optimization
|
||||||
|
|
||||||
|
Adjust limits based on your workload:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 1G # Increase for heavy workloads
|
||||||
|
cpus: '1.0' # More CPU for concurrent requests
|
||||||
|
```
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
|
||||||
|
Monitor memory usage:
|
||||||
|
```bash
|
||||||
|
docker stats zen-mcp-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Adjust Python memory settings if needed:
|
||||||
|
```env
|
||||||
|
PYTHONMALLOC=pymalloc
|
||||||
|
MALLOC_ARENA_MAX=2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration with Claude Desktop
|
||||||
|
|
||||||
|
Configure Claude Desktop to use the containerized server. **Choose one of the configurations below based on your needs:**
|
||||||
|
|
||||||
|
### Option 1: Direct Docker Run (Recommended)
|
||||||
|
|
||||||
|
**The simplest and most reliable option for most users.**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"zen-mcp": {
|
||||||
|
"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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Exemple Windows** :
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"zen-mcp": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"-i",
|
||||||
|
"--env-file",
|
||||||
|
"C:/path/to/zen-mcp-server/.env",
|
||||||
|
"-v",
|
||||||
|
"C:/path/to/zen-mcp-server/logs:/app/logs",
|
||||||
|
"zen-mcp-server:latest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Docker Compose Run (one-shot, uses docker-compose.yml)
|
||||||
|
|
||||||
|
**To use the advanced configuration from docker-compose.yml without a persistent container.**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"zen-mcp": {
|
||||||
|
"command": "docker-compose",
|
||||||
|
"args": [
|
||||||
|
"-f", "/absolute/path/to/zen-mcp-server/docker-compose.yml",
|
||||||
|
"run", "--rm", "zen-mcp"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Inline Environment Variables (Advanced)
|
||||||
|
|
||||||
|
**For highly customized needs.**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"zen-mcp": {
|
||||||
|
"command": "docker",
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
"--rm",
|
||||||
|
"-i",
|
||||||
|
"-e", "GEMINI_API_KEY=your_key_here",
|
||||||
|
"-e", "LOG_LEVEL=INFO",
|
||||||
|
"-e", "DEFAULT_MODEL=auto",
|
||||||
|
"-v", "/path/to/logs:/app/logs",
|
||||||
|
"zen-mcp-server:latest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration Notes
|
||||||
|
|
||||||
|
**Important notes:**
|
||||||
|
- Replace `/absolute/path/to/zen-mcp-server` with the actual path to your project.
|
||||||
|
- Always use forward slashes `/` for Docker volumes, even on Windows.
|
||||||
|
- Ensure the `.env` file exists and contains your API keys.
|
||||||
|
- **Persistent volumes**: Docker Compose options (Options 2) automatically use the `zen-mcp-config` named volume for persistent configuration storage.
|
||||||
|
|
||||||
|
**Environment file requirements:**
|
||||||
|
```env
|
||||||
|
# At least one API key is required
|
||||||
|
GEMINI_API_KEY=your_gemini_key
|
||||||
|
OPENAI_API_KEY=your_openai_key
|
||||||
|
# ... other keys
|
||||||
|
```
|
||||||
|
|
||||||
|
**Troubleshooting:**
|
||||||
|
- If Option 1 fails: check that the Docker image exists (`docker images zen-mcp-server`).
|
||||||
|
- If Option 2 fails: verify the compose file path and ensure the service is not already in use.
|
||||||
|
- Permission issues: make sure the `logs` folder is writable.
|
||||||
|
|
||||||
|
## Advanced Configuration
|
||||||
|
|
||||||
|
### Custom Networks
|
||||||
|
|
||||||
|
For complex deployments:
|
||||||
|
```yaml
|
||||||
|
networks:
|
||||||
|
zen-network:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.20.0.0/16
|
||||||
|
gateway: 172.20.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple Instances
|
||||||
|
|
||||||
|
Run multiple instances with different configurations:
|
||||||
|
```bash
|
||||||
|
# Copy compose file
|
||||||
|
cp docker-compose.yml docker-compose.dev.yml
|
||||||
|
|
||||||
|
# Modify service names and ports
|
||||||
|
# Deploy with custom compose file
|
||||||
|
docker-compose -f docker-compose.dev.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration and Updates
|
||||||
|
|
||||||
|
### Updating the Server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull latest changes
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Rebuild and restart
|
||||||
|
docker-compose down
|
||||||
|
docker-compose build --no-cache
|
||||||
|
./docker/scripts/deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Migration
|
||||||
|
|
||||||
|
When upgrading, configuration is preserved in the named volume `zen-mcp-config`.
|
||||||
|
|
||||||
|
For major version upgrades, check the [CHANGELOG](../CHANGELOG.md) for breaking changes.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For any questions, open an issue on GitHub or consult the official documentation.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Next Steps:**
|
||||||
|
- Review the [Configuration Guide](configuration.md) for detailed environment variable options
|
||||||
|
- Check [Advanced Usage](advanced-usage.md) for custom model configurations
|
||||||
|
- See [Troubleshooting](troubleshooting.md) for common issues and solutions
|
||||||
Reference in New Issue
Block a user