Files
lore-engine-poc-v3/Dockerfile
Lore Engine Dev 29c691a038 docker: drop root in the container (review-2)
- New non-root user 'lore' (uid 10001) created early so --chown
  works on subsequent COPYs. The final USER directive means
  everything reachable from the MCP wire (pickle load, 36 tools
  including 12 mutators) runs as UID 10001, not root.
- --chown=lore:lore on all COPY lines.
- Removed the redundant .graph.pkl COPY (the file is bundled via
  the lore_engine_poc/ directory copy, but the explicit line was
  hiding that — restore the 'override at runtime' instruction in
  the README).
- New test: test_docker_runs_as_non_root — execs 'id -u' inside
  the container and asserts the uid is non-zero.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 19:44:21 -04:00

48 lines
1.8 KiB
Docker

# syntax=docker/dockerfile:1.6
# Lore Engine POC MCP server — Streamable HTTP transport (slice 11.4).
FROM python:3.12-slim
# Sane Python defaults
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
LORE_HTTP_HOST=0.0.0.0 \
LORE_HTTP_PORT=8765
# Create a non-root user early so subsequent --chown works and so the
# final USER directive doesn't need to chown retroactively.
RUN groupadd --system --gid 10001 lore \
&& useradd --system --uid 10001 --gid lore --no-create-home --home-dir /app lore
WORKDIR /app
# Layer 1: requirements (cache-friendly; rebuilds only when deps change)
COPY --chown=lore:lore requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Layer 2: source tree. The pre-built graph (165 KB) lives at
# lore_engine_poc/.graph.pkl and rides along in this layer. For larger
# codexes, override at run time with:
# docker run -v $PWD/data:/data -e LORE_GRAPH_PATH=/data/.graph.pkl
COPY --chown=lore:lore lore_engine_poc ./lore_engine_poc
COPY --chown=lore:lore scripts ./scripts
EXPOSE 8765
# Drop root. Anything reachable from the MCP wire (pickle load, 36
# tools including 12 mutators) now runs as UID 10001, not root.
USER lore
# Healthcheck: same JSON-RPC path an MCP client would use.
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD python -c "import json, urllib.request; \
req = urllib.request.Request('http://127.0.0.1:8765/mcp', \
method='POST', \
data=json.dumps({'jsonrpc':'2.0','id':1,'method':'initialize','params':{}}).encode(), \
headers={'Content-Type':'application/json','Accept':'application/json'}); \
r = json.loads(urllib.request.urlopen(req, timeout=3).read()); \
assert r['result']['protocolVersion'] == '2024-11-05'" \
|| exit 1
CMD ["python", "scripts/06_mcp_http_server.py", "--host", "0.0.0.0"]