add docker support
This commit is contained in:
parent
7b12024005
commit
a2f4c709c5
80
.dockerignore
Normal file
80
.dockerignore
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Git related files
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.gitattributes
|
||||||
|
|
||||||
|
# Python related
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
ENV/
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Operating systems
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
.tmp/
|
||||||
|
|
||||||
|
# Docker related
|
||||||
|
Dockerfile*
|
||||||
|
.dockerignore
|
||||||
|
docker-compose*.yml
|
||||||
|
Makefile
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
*.md
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# Configuration files (avoid including sensitive information)
|
||||||
|
config.yaml
|
||||||
|
*.yaml
|
||||||
|
!config.yaml.sample
|
||||||
|
config/
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.bak
|
||||||
|
*.backup
|
||||||
67
Dockerfile
Normal file
67
Dockerfile
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# Use official Python runtime as base image
|
||||||
|
FROM python:3.11-slim as builder
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies for building
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy requirements file
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
RUN pip install --no-cache-dir --user -r requirements.txt
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Create non-root user for security
|
||||||
|
RUN groupadd -r mcpuser && useradd -r -g mcpuser mcpuser
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install only runtime system dependencies (including bash for entrypoint script)
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
ca-certificates \
|
||||||
|
bash \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Copy Python packages from builder stage
|
||||||
|
COPY --from=builder /root/.local /home/mcpuser/.local
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY server.py .
|
||||||
|
COPY config.yaml.sample .
|
||||||
|
COPY docker-entrypoint.sh .
|
||||||
|
|
||||||
|
# Make entrypoint script executable
|
||||||
|
RUN chmod +x docker-entrypoint.sh
|
||||||
|
|
||||||
|
# Create necessary directories and set permissions
|
||||||
|
RUN mkdir -p /app/logs /app/config \
|
||||||
|
&& chown -R mcpuser:mcpuser /app
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV PATH=/home/mcpuser/.local/bin:$PATH
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER mcpuser
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8080')" || exit 1
|
||||||
|
|
||||||
|
# Set entrypoint and default command
|
||||||
|
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||||
|
CMD ["python", "server.py", "--config", "/app/config/config.yaml"]
|
||||||
114
Makefile
Normal file
114
Makefile
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
# ESXi MCP Server Makefile
|
||||||
|
# Provides convenient commands for Docker operations
|
||||||
|
|
||||||
|
# Variables
|
||||||
|
DOCKER_IMAGE = esxi-mcp-server
|
||||||
|
DOCKER_TAG = latest
|
||||||
|
CONTAINER_NAME = esxi-mcp-server
|
||||||
|
COMPOSE_FILE = docker-compose.yml
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
.PHONY: help
|
||||||
|
help: ## Show this help message
|
||||||
|
@echo "ESXi MCP Server Docker Commands"
|
||||||
|
@echo "================================"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
# Build commands
|
||||||
|
.PHONY: build
|
||||||
|
build: ## Build Docker image
|
||||||
|
docker build -t $(DOCKER_IMAGE):$(DOCKER_TAG) .
|
||||||
|
|
||||||
|
.PHONY: build-no-cache
|
||||||
|
build-no-cache: ## Build Docker image without cache
|
||||||
|
docker build --no-cache -t $(DOCKER_IMAGE):$(DOCKER_TAG) .
|
||||||
|
|
||||||
|
# Run commands
|
||||||
|
.PHONY: run
|
||||||
|
run: ## Run container with docker-compose
|
||||||
|
docker-compose -f $(COMPOSE_FILE) up -d
|
||||||
|
|
||||||
|
.PHONY: run-logs
|
||||||
|
run-logs: ## Run container with docker-compose and show logs
|
||||||
|
docker-compose -f $(COMPOSE_FILE) up
|
||||||
|
|
||||||
|
.PHONY: stop
|
||||||
|
stop: ## Stop running containers
|
||||||
|
docker-compose -f $(COMPOSE_FILE) down
|
||||||
|
|
||||||
|
.PHONY: restart
|
||||||
|
restart: ## Restart containers
|
||||||
|
docker-compose -f $(COMPOSE_FILE) restart
|
||||||
|
|
||||||
|
# Development commands
|
||||||
|
.PHONY: logs
|
||||||
|
logs: ## Show container logs
|
||||||
|
docker-compose -f $(COMPOSE_FILE) logs -f
|
||||||
|
|
||||||
|
.PHONY: shell
|
||||||
|
shell: ## Open bash shell in running container
|
||||||
|
docker exec -it $(CONTAINER_NAME) bash
|
||||||
|
|
||||||
|
.PHONY: status
|
||||||
|
status: ## Show container status
|
||||||
|
docker-compose -f $(COMPOSE_FILE) ps
|
||||||
|
|
||||||
|
# Maintenance commands
|
||||||
|
.PHONY: clean
|
||||||
|
clean: ## Remove containers and volumes
|
||||||
|
docker-compose -f $(COMPOSE_FILE) down -v
|
||||||
|
docker rmi $(DOCKER_IMAGE):$(DOCKER_TAG) 2>/dev/null || true
|
||||||
|
|
||||||
|
.PHONY: clean-all
|
||||||
|
clean-all: ## Remove everything including images and volumes
|
||||||
|
docker-compose -f $(COMPOSE_FILE) down -v --rmi all
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
|
.PHONY: update
|
||||||
|
update: ## Update container (rebuild and restart)
|
||||||
|
make stop
|
||||||
|
make build
|
||||||
|
make run
|
||||||
|
|
||||||
|
# Setup commands
|
||||||
|
.PHONY: setup
|
||||||
|
setup: ## Initial setup - create directories and sample config
|
||||||
|
mkdir -p logs config
|
||||||
|
cp config.yaml.sample config/config.yaml || true
|
||||||
|
@echo "Setup complete! Please edit config/config.yaml with your vCenter details."
|
||||||
|
|
||||||
|
.PHONY: env-example
|
||||||
|
env-example: ## Create .env.example file
|
||||||
|
@echo "# VMware vCenter/ESXi Configuration" > .env.example
|
||||||
|
@echo "VCENTER_HOST=your-vcenter-ip-or-hostname" >> .env.example
|
||||||
|
@echo "VCENTER_USER=administrator@vsphere.local" >> .env.example
|
||||||
|
@echo "VCENTER_PASSWORD=your-password" >> .env.example
|
||||||
|
@echo "" >> .env.example
|
||||||
|
@echo "# Optional VMware Configuration" >> .env.example
|
||||||
|
@echo "VCENTER_DATACENTER=your-datacenter-name" >> .env.example
|
||||||
|
@echo "VCENTER_CLUSTER=your-cluster-name" >> .env.example
|
||||||
|
@echo "VCENTER_DATASTORE=your-datastore-name" >> .env.example
|
||||||
|
@echo "VCENTER_NETWORK=VM Network" >> .env.example
|
||||||
|
@echo "" >> .env.example
|
||||||
|
@echo "# Security Settings" >> .env.example
|
||||||
|
@echo "VCENTER_INSECURE=true" >> .env.example
|
||||||
|
@echo "MCP_API_KEY=your-api-key-here" >> .env.example
|
||||||
|
@echo "" >> .env.example
|
||||||
|
@echo "# Logging Configuration" >> .env.example
|
||||||
|
@echo "MCP_LOG_LEVEL=INFO" >> .env.example
|
||||||
|
@echo ".env.example file created!"
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
.PHONY: health
|
||||||
|
health: ## Check container health
|
||||||
|
docker exec $(CONTAINER_NAME) python -c "import urllib.request; urllib.request.urlopen('http://localhost:8080')" && echo "✅ Health check passed" || echo "❌ Health check failed"
|
||||||
|
|
||||||
|
# Quick start
|
||||||
|
.PHONY: quick-start
|
||||||
|
quick-start: ## Quick start with environment variables (requires .env file)
|
||||||
|
@echo "Starting with environment variables..."
|
||||||
|
@echo "Make sure you have created a .env file with your configuration!"
|
||||||
|
docker-compose -f $(COMPOSE_FILE) up -d
|
||||||
|
|
||||||
|
.PHONY: dev
|
||||||
|
dev: build run-logs ## Development mode: build and run with logs
|
||||||
286
README_DOCKER.md
Normal file
286
README_DOCKER.md
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
# ESXi MCP Server - Docker Guide
|
||||||
|
|
||||||
|
This guide provides instructions for running the ESXi MCP Server using Docker and Docker Compose.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Docker 20.10+
|
||||||
|
- Docker Compose 2.0+
|
||||||
|
- Access to a VMware vCenter Server or ESXi host
|
||||||
|
|
||||||
|
### 1. Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone <repository-url>
|
||||||
|
cd esxi-mcp-server
|
||||||
|
|
||||||
|
# Create necessary directories and configuration
|
||||||
|
make setup
|
||||||
|
|
||||||
|
# Create environment variables file (optional)
|
||||||
|
make env-example
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Configuration
|
||||||
|
|
||||||
|
You have two options for configuration:
|
||||||
|
|
||||||
|
#### Option A: Configuration File (Recommended)
|
||||||
|
|
||||||
|
Edit `config/config.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
vcenter_host: "your-vcenter-ip"
|
||||||
|
vcenter_user: "administrator@vsphere.local"
|
||||||
|
vcenter_password: "your-password"
|
||||||
|
datacenter: "your-datacenter"
|
||||||
|
cluster: "your-cluster"
|
||||||
|
datastore: "your-datastore"
|
||||||
|
network: "VM Network"
|
||||||
|
insecure: true
|
||||||
|
api_key: "your-api-key"
|
||||||
|
log_level: "INFO"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Option B: Environment Variables
|
||||||
|
|
||||||
|
Edit `.env` file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
VCENTER_HOST=your-vcenter-ip
|
||||||
|
VCENTER_USER=administrator@vsphere.local
|
||||||
|
VCENTER_PASSWORD=your-password
|
||||||
|
VCENTER_DATACENTER=your-datacenter
|
||||||
|
VCENTER_CLUSTER=your-cluster
|
||||||
|
VCENTER_DATASTORE=your-datastore
|
||||||
|
VCENTER_NETWORK=VM Network
|
||||||
|
VCENTER_INSECURE=true
|
||||||
|
MCP_API_KEY=your-api-key
|
||||||
|
MCP_LOG_LEVEL=INFO
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Run the Server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and run
|
||||||
|
make dev
|
||||||
|
|
||||||
|
# Or run in background
|
||||||
|
make run
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
make status
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
make logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available Commands
|
||||||
|
|
||||||
|
Use `make help` to see all available commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
|
||||||
|
- `make build` - Build Docker image
|
||||||
|
- `make build-no-cache` - Build without cache
|
||||||
|
|
||||||
|
### Run Commands
|
||||||
|
|
||||||
|
- `make run` - Run in background
|
||||||
|
- `make run-logs` - Run with logs
|
||||||
|
- `make stop` - Stop containers
|
||||||
|
- `make restart` - Restart containers
|
||||||
|
|
||||||
|
### Development Commands
|
||||||
|
|
||||||
|
- `make dev` - Development mode (build + run with logs)
|
||||||
|
- `make logs` - Show logs
|
||||||
|
- `make shell` - Open bash shell in container
|
||||||
|
- `make status` - Show container status
|
||||||
|
- `make health` - Check container health
|
||||||
|
|
||||||
|
### Maintenance Commands
|
||||||
|
|
||||||
|
- `make clean` - Remove containers and volumes
|
||||||
|
- `make clean-all` - Remove everything
|
||||||
|
- `make update` - Rebuild and restart
|
||||||
|
|
||||||
|
## Docker Architecture
|
||||||
|
|
||||||
|
### Multi-stage Build
|
||||||
|
|
||||||
|
The Dockerfile uses a multi-stage build process:
|
||||||
|
|
||||||
|
1. **Builder Stage**: Installs build dependencies and Python packages
|
||||||
|
2. **Production Stage**: Creates a minimal runtime image
|
||||||
|
|
||||||
|
### Security Features
|
||||||
|
|
||||||
|
- Runs as non-root user (`mcpuser`)
|
||||||
|
- Minimal base image (python:3.11-slim)
|
||||||
|
- Only necessary runtime dependencies
|
||||||
|
- Configurable resource limits
|
||||||
|
|
||||||
|
### Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
/app/
|
||||||
|
├── server.py # Main application
|
||||||
|
├── config.yaml.sample # Configuration template
|
||||||
|
├── docker-entrypoint.sh # Startup script
|
||||||
|
├── config/ # Configuration directory (mounted)
|
||||||
|
│ └── config.yaml # Runtime configuration
|
||||||
|
└── logs/ # Log directory (mounted)
|
||||||
|
└── vmware_mcp.log # Application logs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### Volume Mounts
|
||||||
|
|
||||||
|
- `./config.yaml:/app/config/config.yaml:ro` - Configuration file (read-only)
|
||||||
|
- `./logs:/app/logs` - Log directory
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
All configuration options can be set via environment variables:
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|----------|-------------|---------|
|
||||||
|
| `VCENTER_HOST` | vCenter/ESXi hostname | Required |
|
||||||
|
| `VCENTER_USER` | Username | Required |
|
||||||
|
| `VCENTER_PASSWORD` | Password | Required |
|
||||||
|
| `VCENTER_DATACENTER` | Datacenter name | Auto-detect |
|
||||||
|
| `VCENTER_CLUSTER` | Cluster name | Auto-detect |
|
||||||
|
| `VCENTER_DATASTORE` | Datastore name | Auto-detect |
|
||||||
|
| `VCENTER_NETWORK` | Network name | VM Network |
|
||||||
|
| `VCENTER_INSECURE` | Skip SSL verification | true |
|
||||||
|
| `MCP_API_KEY` | API authentication key | None |
|
||||||
|
| `MCP_LOG_LEVEL` | Log level | INFO |
|
||||||
|
|
||||||
|
### Resource Limits
|
||||||
|
|
||||||
|
Default resource limits in docker-compose.yml:
|
||||||
|
|
||||||
|
- **Memory**: 512MB limit, 256MB reserved
|
||||||
|
- **CPU**: 0.5 cores limit, 0.25 cores reserved
|
||||||
|
|
||||||
|
## Health Checks
|
||||||
|
|
||||||
|
The container includes automatic health checks:
|
||||||
|
|
||||||
|
- **Interval**: 30 seconds
|
||||||
|
- **Timeout**: 10 seconds
|
||||||
|
- **Retries**: 3
|
||||||
|
- **Start Period**: 40 seconds
|
||||||
|
|
||||||
|
Check health manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
The server exposes:
|
||||||
|
|
||||||
|
- **Port 8080**: HTTP API endpoint
|
||||||
|
- **Path `/sse`**: Server-Sent Events endpoint
|
||||||
|
- **Path `/sse/messages`**: JSON-RPC messages endpoint
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Check Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check Container Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make status
|
||||||
|
```
|
||||||
|
|
||||||
|
### Open Shell in Container
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make shell
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Configuration not found**: Ensure `config/config.yaml` exists or environment variables are set
|
||||||
|
2. **Permission denied**: Check that the `logs` directory is writable
|
||||||
|
3. **Connection failed**: Verify vCenter/ESXi connectivity and credentials
|
||||||
|
4. **Health check failed**: Check if the server is responding on port 8080
|
||||||
|
|
||||||
|
### Debug Mode
|
||||||
|
|
||||||
|
Run with debug logging:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set in .env file
|
||||||
|
MCP_LOG_LEVEL=DEBUG
|
||||||
|
|
||||||
|
# Or in config.yaml
|
||||||
|
log_level: "DEBUG"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### Security Recommendations
|
||||||
|
|
||||||
|
1. Use a dedicated user account for vCenter access
|
||||||
|
2. Enable API key authentication
|
||||||
|
3. Use valid SSL certificates (set `insecure: false`)
|
||||||
|
4. Limit container resources
|
||||||
|
5. Use Docker secrets for sensitive data
|
||||||
|
|
||||||
|
### High Availability
|
||||||
|
|
||||||
|
For production deployments, consider:
|
||||||
|
|
||||||
|
- Running multiple container instances
|
||||||
|
- Using a load balancer
|
||||||
|
- Implementing persistent storage for logs
|
||||||
|
- Setting up monitoring and alerting
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start the server
|
||||||
|
make run
|
||||||
|
|
||||||
|
# Check if it's working
|
||||||
|
curl http://localhost:8080/sse
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Authentication
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# With API key
|
||||||
|
curl -H "Authorization: Bearer your-api-key" http://localhost:8080/sse
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development workflow
|
||||||
|
make build
|
||||||
|
make dev
|
||||||
|
|
||||||
|
# Make changes to code
|
||||||
|
# Rebuild and restart
|
||||||
|
make update
|
||||||
|
```
|
||||||
49
docker-compose.yml
Normal file
49
docker-compose.yml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
esxi-mcp-server:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: esxi-mcp-server
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
# Mount configuration file
|
||||||
|
- ./config.yaml:/app/config/config.yaml:ro
|
||||||
|
# Mount logs directory
|
||||||
|
- ./logs:/app/logs
|
||||||
|
environment:
|
||||||
|
# Configuration can be overridden via environment variables
|
||||||
|
- VCENTER_HOST=${VCENTER_HOST:-}
|
||||||
|
- VCENTER_USER=${VCENTER_USER:-}
|
||||||
|
- VCENTER_PASSWORD=${VCENTER_PASSWORD:-}
|
||||||
|
- VCENTER_DATACENTER=${VCENTER_DATACENTER:-}
|
||||||
|
- VCENTER_CLUSTER=${VCENTER_CLUSTER:-}
|
||||||
|
- VCENTER_DATASTORE=${VCENTER_DATASTORE:-}
|
||||||
|
- VCENTER_NETWORK=${VCENTER_NETWORK:-VM Network}
|
||||||
|
- VCENTER_INSECURE=${VCENTER_INSECURE:-true}
|
||||||
|
- MCP_API_KEY=${MCP_API_KEY:-}
|
||||||
|
- MCP_LOG_LEVEL=${MCP_LOG_LEVEL:-INFO}
|
||||||
|
networks:
|
||||||
|
- mcp-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080')"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
# Resource limits
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
cpus: '0.5'
|
||||||
|
reservations:
|
||||||
|
memory: 256M
|
||||||
|
cpus: '0.25'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mcp-network:
|
||||||
|
driver: bridge
|
||||||
93
docker-entrypoint.sh
Normal file
93
docker-entrypoint.sh
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Docker entrypoint script for ESXi MCP Server
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Function to wait for configuration file
|
||||||
|
wait_for_config() {
|
||||||
|
local config_file="/app/config/config.yaml"
|
||||||
|
local max_wait=30
|
||||||
|
local count=0
|
||||||
|
|
||||||
|
echo "Waiting for configuration file..."
|
||||||
|
while [ ! -f "$config_file" ] && [ $count -lt $max_wait ]; do
|
||||||
|
echo "Configuration file not found, waiting... ($count/$max_wait)"
|
||||||
|
sleep 2
|
||||||
|
count=$((count + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "$config_file" ]; then
|
||||||
|
echo "Warning: Configuration file not found. Using environment variables."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Configuration file found: $config_file"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to validate required environment variables
|
||||||
|
validate_env() {
|
||||||
|
local required_vars=("VCENTER_HOST" "VCENTER_USER" "VCENTER_PASSWORD")
|
||||||
|
local missing_vars=()
|
||||||
|
|
||||||
|
for var in "${required_vars[@]}"; do
|
||||||
|
if [ -z "${!var}" ]; then
|
||||||
|
missing_vars+=("$var")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#missing_vars[@]} -ne 0 ]; then
|
||||||
|
echo "Error: Missing required environment variables: ${missing_vars[*]}"
|
||||||
|
echo "Please set these variables or provide a configuration file."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create configuration from environment variables
|
||||||
|
create_config_from_env() {
|
||||||
|
local config_file="/app/config/config.yaml"
|
||||||
|
|
||||||
|
echo "Creating configuration from environment variables..."
|
||||||
|
|
||||||
|
cat > "$config_file" << EOF
|
||||||
|
vcenter_host: "${VCENTER_HOST}"
|
||||||
|
vcenter_user: "${VCENTER_USER}"
|
||||||
|
vcenter_password: "${VCENTER_PASSWORD}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Add optional configuration
|
||||||
|
[ -n "$VCENTER_DATACENTER" ] && echo "datacenter: \"${VCENTER_DATACENTER}\"" >> "$config_file"
|
||||||
|
[ -n "$VCENTER_CLUSTER" ] && echo "cluster: \"${VCENTER_CLUSTER}\"" >> "$config_file"
|
||||||
|
[ -n "$VCENTER_DATASTORE" ] && echo "datastore: \"${VCENTER_DATASTORE}\"" >> "$config_file"
|
||||||
|
[ -n "$VCENTER_NETWORK" ] && echo "network: \"${VCENTER_NETWORK}\"" >> "$config_file"
|
||||||
|
[ -n "$VCENTER_INSECURE" ] && echo "insecure: ${VCENTER_INSECURE}" >> "$config_file"
|
||||||
|
[ -n "$MCP_API_KEY" ] && echo "api_key: \"${MCP_API_KEY}\"" >> "$config_file"
|
||||||
|
[ -n "$MCP_LOG_LEVEL" ] && echo "log_level: \"${MCP_LOG_LEVEL}\"" >> "$config_file"
|
||||||
|
|
||||||
|
# Always set log file path
|
||||||
|
echo "log_file: \"/app/logs/vmware_mcp.log\"" >> "$config_file"
|
||||||
|
|
||||||
|
echo "Configuration file created successfully."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
echo "Starting ESXi MCP Server..."
|
||||||
|
|
||||||
|
# Create logs directory if it doesn't exist
|
||||||
|
mkdir -p /app/logs
|
||||||
|
|
||||||
|
# Check if configuration file exists, if not try to create from environment
|
||||||
|
if ! wait_for_config; then
|
||||||
|
validate_env
|
||||||
|
create_config_from_env
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Print configuration info (without sensitive data)
|
||||||
|
echo "Server starting with configuration:"
|
||||||
|
echo " Host: ${VCENTER_HOST:-'from config file'}"
|
||||||
|
echo " User: ${VCENTER_USER:-'from config file'}"
|
||||||
|
echo " Log Level: ${MCP_LOG_LEVEL:-INFO}"
|
||||||
|
echo " Port: 8080"
|
||||||
|
|
||||||
|
# Execute the main command
|
||||||
|
exec "$@"
|
||||||
Loading…
x
Reference in New Issue
Block a user