-
Notifications
You must be signed in to change notification settings - Fork 4
feat: add Docker support for HTTP-based MCP server #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,87 @@ | ||||||||||
| name: Build and Publish Docker Image | ||||||||||
|
|
||||||||||
| on: | ||||||||||
| release: | ||||||||||
| types: [published] | ||||||||||
| push: | ||||||||||
| branches: [main] | ||||||||||
| paths: | ||||||||||
| - 'src/**' | ||||||||||
| - 'pyproject.toml' | ||||||||||
| - 'uv.lock' | ||||||||||
| - 'Dockerfile' | ||||||||||
| - '.github/workflows/docker-publish.yml' | ||||||||||
| workflow_dispatch: | ||||||||||
| inputs: | ||||||||||
| tag: | ||||||||||
| description: 'Image tag (defaults to branch name or "manual")' | ||||||||||
| required: false | ||||||||||
| default: '' | ||||||||||
|
|
||||||||||
| env: | ||||||||||
| REGISTRY: ghcr.io | ||||||||||
| IMAGE_NAME: ${{ github.repository }} | ||||||||||
|
|
||||||||||
| jobs: | ||||||||||
| build-and-push: | ||||||||||
| runs-on: ubuntu-latest | ||||||||||
| permissions: | ||||||||||
| contents: read | ||||||||||
| packages: write | ||||||||||
|
||||||||||
| packages: write | |
| packages: write | |
| id-token: write | |
| attestations: write |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The step "Build and push Docker image" is missing an id attribute. Line 83 references steps.build-push.outputs.digest, but this step doesn't have id: build-push, causing the attestation step to fail.
Add id: build-push to this step:
- name: Build and push Docker image
id: build-push
uses: docker/build-push-action@v6| - name: Build and push Docker image | |
| - name: Build and push Docker image | |
| id: build-push |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # DataBeak MCP Server - HTTP Mode | ||
| # Multi-stage build for minimal production image | ||
|
|
||
| # Build stage - install dependencies with uv | ||
| FROM python:3.12-slim AS builder | ||
|
|
||
| # Install uv for fast dependency management (pinned for reproducibility) | ||
| COPY --from=ghcr.io/astral-sh/uv:0.5.18 /uv /uvx /bin/ | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy dependency files first for better layer caching | ||
| # README.md is required by pyproject.toml for package metadata | ||
| COPY pyproject.toml uv.lock README.md ./ | ||
|
|
||
| # Create virtual environment and install production dependencies only | ||
| RUN uv sync --frozen --no-dev --no-install-project | ||
|
|
||
| # Copy source code | ||
| COPY src/ ./src/ | ||
|
|
||
| # Install the project itself | ||
| RUN uv sync --frozen --no-dev | ||
|
|
||
|
|
||
| # Production stage - minimal runtime image | ||
| FROM python:3.12-slim AS runtime | ||
|
|
||
| # Security: run as non-root user | ||
| RUN groupadd --gid 1000 databeak \ | ||
| && useradd --uid 1000 --gid 1000 --shell /bin/bash --create-home databeak | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy virtual environment from builder | ||
| COPY --from=builder /app/.venv /app/.venv | ||
|
|
||
| # Copy source code | ||
| COPY --from=builder /app/src /app/src | ||
|
|
||
| # Set environment variables | ||
| ENV PATH="/app/.venv/bin:$PATH" \ | ||
| PYTHONUNBUFFERED=1 \ | ||
| PYTHONDONTWRITEBYTECODE=1 | ||
|
|
||
| # Switch to non-root user | ||
| USER databeak | ||
|
|
||
| # Expose HTTP port | ||
| EXPOSE 8000 | ||
|
|
||
| # Health check for container orchestration (uses stdlib to avoid dependency on httpx) | ||
| HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ | ||
| CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=5)" | ||
|
|
||
| # Run the MCP server in HTTP mode | ||
| ENTRYPOINT ["python", "-m", "databeak.server"] | ||
| CMD ["--transport", "http", "--host", "0.0.0.0", "--port", "8000"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
*.mdexclusion pattern on line 68 will excludesrc/databeak/instructions.md, which is required by the server at runtime (loaded inserver.py:41-46). While the code has fallback handling, this will cause a warning log and the server will run with "Instructions file not available" instead of the proper instructions.Add an exception for the instructions file: