Add Docker scripts and validation tests for Zen MCP Server

- Created build.sh script for building the Docker image with environment variable checks.
- Added deploy.sh script for deploying the Zen MCP Server with health checks and logging.
- Implemented healthcheck.py to verify server process, Python imports, log directory, and environment variables.
- Developed comprehensive tests for Docker configuration, environment validation, and integration with MCP.
- Included performance tests for Docker image size and startup time.
- Added validation script tests to ensure proper Docker and MCP setup.
This commit is contained in:
OhMyApps
2025-06-25 16:00:48 +02:00
parent 8b7620b262
commit 2de9839096
11 changed files with 1820 additions and 0 deletions

41
docker/scripts/build.sh Normal file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
set -euo pipefail
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${GREEN}=== Building Zen MCP Server Docker Image ===${NC}"
# Check if .env file exists
if [[ ! -f .env ]]; then
echo -e "${YELLOW}Warning: .env file not found. Copying from .env.example${NC}"
if [[ -f .env.example ]]; then
cp .env.example .env
echo -e "${YELLOW}Please edit .env file with your API keys before running the server${NC}"
else
echo -e "${RED}Error: .env.example not found${NC}"
exit 1
fi
fi
# Build the Docker image
echo -e "${GREEN}Building Docker image...${NC}"
docker-compose build --no-cache
# Verify the build
if docker images | grep -q "zen-mcp-server"; then
echo -e "${GREEN}✓ Docker image built successfully${NC}"
echo -e "${GREEN}Image details:${NC}"
docker images | grep zen-mcp-server
else
echo -e "${RED}✗ Failed to build Docker image${NC}"
exit 1
fi
echo -e "${GREEN}=== Build Complete ===${NC}"
echo -e "${YELLOW}Next steps:${NC}"
echo -e " 1. Edit .env file with your API keys"
echo -e " 2. Run: ${GREEN}docker-compose up -d${NC}"

74
docker/scripts/deploy.sh Normal file
View File

@@ -0,0 +1,74 @@
#!/bin/bash
set -euo pipefail
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${GREEN}=== Deploying Zen MCP Server ===${NC}"
# Function to check if required environment variables are set
check_env_vars() {
local required_vars=("GOOGLE_API_KEY" "OPENAI_API_KEY")
local missing_vars=()
for var in "${required_vars[@]}"; do
if [[ -z "${!var:-}" ]]; then
missing_vars+=("$var")
fi
done
if [[ ${#missing_vars[@]} -gt 0 ]]; then
echo -e "${RED}Error: Missing required environment variables:${NC}"
printf ' %s\n' "${missing_vars[@]}"
echo -e "${YELLOW}Please set these variables in your .env file${NC}"
exit 1
fi
}
# Load environment variables
if [[ -f .env ]]; then
set -a
source .env
set +a
echo -e "${GREEN}✓ Environment variables loaded from .env${NC}"
else
echo -e "${RED}Error: .env file not found${NC}"
echo -e "${YELLOW}Please copy .env.example to .env and configure your API keys${NC}"
exit 1
fi
# Check required environment variables
check_env_vars
# Create logs directory if it doesn't exist
mkdir -p logs
# Stop existing containers
echo -e "${GREEN}Stopping existing containers...${NC}"
docker-compose down
# Start the services
echo -e "${GREEN}Starting Zen MCP Server...${NC}"
docker-compose up -d
# Wait for health check
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' || {
echo -e "${RED}Service failed to become healthy${NC}"
echo -e "${YELLOW}Checking logs:${NC}"
docker-compose logs zen-mcp
exit 1
}
echo -e "${GREEN}✓ Zen MCP Server deployed successfully${NC}"
echo -e "${GREEN}Service Status:${NC}"
docker-compose ps
echo -e "${GREEN}=== Deployment Complete ===${NC}"
echo -e "${YELLOW}Useful commands:${NC}"
echo -e " View logs: ${GREEN}docker-compose logs -f zen-mcp${NC}"
echo -e " Stop service: ${GREEN}docker-compose down${NC}"
echo -e " Restart service: ${GREEN}docker-compose restart zen-mcp${NC}"

View File

@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""
Health check script for Zen MCP Server Docker container
"""
import os
import subprocess
import sys
def check_process():
"""Check if the main server process is running"""
try:
result = subprocess.run(["pgrep", "-f", "server.py"], capture_output=True, text=True)
return result.returncode == 0
except Exception as e:
print(f"Process check failed: {e}", file=sys.stderr)
return False
def check_python_imports():
"""Check if critical Python modules can be imported"""
critical_modules = ["mcp", "google.genai", "openai", "pydantic", "dotenv"]
for module in critical_modules:
try:
__import__(module)
except ImportError as e:
print(f"Critical module {module} cannot be imported: {e}", file=sys.stderr)
return False
except Exception as e:
print(f"Error importing {module}: {e}", file=sys.stderr)
return False
return True
def check_log_directory():
"""Check if logs directory is writable"""
log_dir = "/app/logs"
try:
if not os.path.exists(log_dir):
print(f"Log directory {log_dir} does not exist", file=sys.stderr)
return False
test_file = os.path.join(log_dir, ".health_check")
with open(test_file, "w") as f:
f.write("health_check")
os.remove(test_file)
return True
except Exception as e:
print(f"Log directory check failed: {e}", file=sys.stderr)
return False
def check_environment():
"""Check if essential environment variables are present"""
# At least one API key should be present
api_keys = [
"GEMINI_API_KEY",
"GOOGLE_API_KEY",
"OPENAI_API_KEY",
"XAI_API_KEY",
"DIAL_API_KEY",
"OPENROUTER_API_KEY",
]
has_api_key = any(os.getenv(key) for key in api_keys)
if not has_api_key:
print("No API keys found in environment", file=sys.stderr)
return False
return True
def main():
"""Main health check function"""
checks = [
("Process", check_process),
("Python imports", check_python_imports),
("Log directory", check_log_directory),
("Environment", check_environment),
]
failed_checks = []
for check_name, check_func in checks:
if not check_func():
failed_checks.append(check_name)
if failed_checks:
print(f"Health check failed: {', '.join(failed_checks)}", file=sys.stderr)
sys.exit(1)
print("Health check passed")
sys.exit(0)
if __name__ == "__main__":
main()