diff --git a/surfsense_mcp/.dockerignore b/surfsense_mcp/.dockerignore new file mode 100644 index 000000000..28abd4591 --- /dev/null +++ b/surfsense_mcp/.dockerignore @@ -0,0 +1,11 @@ +.git +.gitignore +.venv +__pycache__/ +*.py[cod] +*$py.class +*.so +.pytest_cache/ +.ruff_cache/ +.env +tests/ diff --git a/surfsense_mcp/Dockerfile b/surfsense_mcp/Dockerfile new file mode 100644 index 000000000..2233411ed --- /dev/null +++ b/surfsense_mcp/Dockerfile @@ -0,0 +1,32 @@ +# syntax=docker.io/docker/dockerfile:1 +# SurfSense MCP Server — remote (streamable-http) image. +# Serves /mcp (per-request API key, no baked secret) and a public /health probe. + +# Stage 1: deps frozen from uv.lock so rebuilds never drift. +FROM python:3.12-slim AS deps + +WORKDIR /app + +COPY pyproject.toml uv.lock ./ +RUN pip install --no-cache-dir uv && \ + uv export --frozen --no-dev --no-emit-project --no-hashes \ + --format requirements-txt -o /tmp/requirements.txt && \ + uv pip install --system --no-cache-dir -r /tmp/requirements.txt && \ + rm /tmp/requirements.txt + + +# Stage 2: project source; --no-deps since deps are already installed above. +FROM deps AS production + +COPY . . +RUN uv pip install --system --no-cache-dir --no-deps -e . + +ENV PYTHONUNBUFFERED=1 \ + SURFSENSE_MCP_TRANSPORT=streamable-http \ + SURFSENSE_MCP_HOST=0.0.0.0 \ + SURFSENSE_MCP_PORT=8080 \ + SURFSENSE_BASE_URL=https://api.surfsense.com + +EXPOSE 8080 + +CMD ["python", "-m", "surfsense_mcp"]