From d21f85545bade8e7a3679cd691de33f13db0b68d Mon Sep 17 00:00:00 2001 From: lmiranda Date: Tue, 3 Feb 2026 16:10:06 -0500 Subject: [PATCH] Create Docker deployment infrastructure This commit provides production-ready Docker deployment for the HTTP MCP wrapper. Components: - Dockerfile: Multi-stage build for optimized image size - Builder stage: Compiles dependencies and installs packages - Production stage: Minimal runtime image with only necessary files - Python 3.11 slim base image - Health check endpoint integration - Proper Python environment variables (unbuffered, no bytecode) - docker-compose.yml: Complete orchestration setup - Service configuration with restart policy - Port mapping (8000:8000) - Environment variable passthrough - Health check configuration - Isolated network - Ready for production deployment - .dockerignore: Optimized build context - Excludes Python cache, virtual environments, IDE files - Excludes tests and documentation - Reduces image size and build time - .env.docker.example: Docker-specific environment template - All required Gitea configuration - Optional authentication settings - Optional tool filtering settings Deployment: 1. Copy .env.docker.example to .env 2. Fill in Gitea credentials 3. Run: docker-compose up -d 4. Access at http://localhost:8000 This infrastructure enables easy deployment to any Docker-compatible environment (local, cloud, Kubernetes). Closes #15 Co-Authored-By: Claude Opus 4.5 --- .dockerignore | 67 +++++++++++++++++++++++++++++++++++++++++++++ .env.docker.example | 19 +++++++++++++ Dockerfile | 54 ++++++++++++++++++++++++++++++++++++ docker-compose.yml | 43 +++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.docker.example create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a31935e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,67 @@ +# Python +__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 +*.coverage +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ + +# Virtual environments +venv/ +env/ +ENV/ +.venv/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Git +.git/ +.gitignore +.gitattributes + +# Documentation +*.md +docs/ + +# CI/CD +.github/ +.gitlab-ci.yml + +# Environment files +.env +.env.* +!.env.example + +# Claude Code +.claude/ + +# Docker +.dockerignore +docker-compose.override.yml + +# Test files +tests/ diff --git a/.env.docker.example b/.env.docker.example new file mode 100644 index 0000000..ce3bbf4 --- /dev/null +++ b/.env.docker.example @@ -0,0 +1,19 @@ +# Docker Compose Environment Variables +# Copy this file to .env and fill in your values + +# Gitea Configuration (REQUIRED) +GITEA_URL=https://gitea.example.com +GITEA_TOKEN=your_gitea_api_token_here +GITEA_OWNER=your_username_or_org +GITEA_REPO=your_repo_name + +# Authentication Configuration (OPTIONAL) +# Uncomment to enable Bearer token authentication +# AUTH_TOKEN=your_bearer_token_here + +# Tool Filtering Configuration (OPTIONAL) +# Uncomment to enable specific tools only (whitelist mode) +# ENABLED_TOOLS=list_issues,create_issue,update_issue,list_labels + +# Uncomment to disable specific tools (blacklist mode) +# DISABLED_TOOLS=delete_issue,close_milestone diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d560fd9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,54 @@ +# Gitea HTTP MCP Wrapper Dockerfile +# Multi-stage build for optimized image size + +FROM python:3.11-slim as builder + +# Set working directory +WORKDIR /build + +# Install build dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gcc \ + && rm -rf /var/lib/apt/lists/* + +# Copy requirements first for better caching +COPY requirements.txt . +RUN pip install --user --no-cache-dir -r requirements.txt + +# Copy source code +COPY pyproject.toml . +COPY src/ src/ + +# Install package +RUN pip install --user --no-cache-dir -e . + +# Production stage +FROM python:3.11-slim + +# Set working directory +WORKDIR /app + +# Copy installed packages from builder +COPY --from=builder /root/.local /root/.local + +# Copy source code +COPY src/ src/ +COPY pyproject.toml . + +# Make sure scripts in .local are usable +ENV PATH=/root/.local/bin:$PATH + +# Set Python environment variables +ENV PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE=1 + +# Expose default port +EXPOSE 8000 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()" + +# Run the HTTP MCP server +CMD ["gitea-http-wrapper"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d1b503c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,43 @@ +version: '3.8' + +services: + gitea-mcp-wrapper: + build: + context: . + dockerfile: Dockerfile + image: gitea-mcp-wrapper:latest + container_name: gitea-mcp-wrapper + restart: unless-stopped + ports: + - "8000:8000" + environment: + # Gitea Configuration + - GITEA_URL=${GITEA_URL} + - GITEA_TOKEN=${GITEA_TOKEN} + - GITEA_OWNER=${GITEA_OWNER} + - GITEA_REPO=${GITEA_REPO} + + # HTTP Server Configuration + - HTTP_HOST=0.0.0.0 + - HTTP_PORT=8000 + + # Authentication (Optional) + - AUTH_TOKEN=${AUTH_TOKEN:-} + + # Tool Filtering (Optional) + - ENABLED_TOOLS=${ENABLED_TOOLS:-} + - DISABLED_TOOLS=${DISABLED_TOOLS:-} + + healthcheck: + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s + + networks: + - gitea-mcp-network + +networks: + gitea-mcp-network: + driver: bridge