-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDockerfile
More file actions
49 lines (40 loc) · 2.09 KB
/
Copy pathDockerfile
File metadata and controls
49 lines (40 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
FROM python:3.14-slim
# Runs as this instead of root -- the server only reads outbound HTTP and
# holds in-memory caches, no reason for it to run with root's filesystem
# reach if a dependency (or the process itself) is ever compromised.
RUN useradd --create-home --uid 1000 --shell /usr/sbin/nologin appuser
WORKDIR /app
RUN pip install --no-cache-dir uv
# Manifests first so this layer caches across source-only changes.
COPY pyproject.toml uv.lock ./
# Source before install: pyproject.toml declares helpers/tools/prompts/
# resources as this package's own directories, and readme="README.md" in
# its build metadata -- installing before those exist (as the previous
# `pip install .` before `COPY . .` did) produces an incomplete
# distribution that only ran because the later COPY put raw source files
# on the working directory anyway, not because the install itself worked.
COPY helpers/ helpers/
COPY tools/ tools/
COPY prompts/ prompts/
COPY resources/ resources/
# scripts/ isn't imported by the server itself, but stays in the image so an
# operator can run its one-off data-fetch/smoke-test scripts via
# `docker compose exec mcp uv run python scripts/<name>.py`.
COPY scripts/ scripts/
COPY main.py README.md ./
# --locked: fail the build rather than silently re-resolving if uv.lock
# and pyproject.toml ever drift, instead of installing whatever versions
# happen to be newest that day (the previous plain `pip install .` had no
# lockfile at all, so Docker and CI could end up on different dependency
# graphs from the same commit).
RUN uv sync --locked --no-dev
# /app/data doesn't exist yet -- it's only created at runtime by
# scripts/build_supercias_financials_db.py, and docker-compose.yml mounts a
# named volume there. Docker copies a fresh named volume's initial
# ownership from whatever's already at that path in the image, so this has
# to exist (owned by appuser) before that mount happens, or the volume
# comes up root-owned and that script can't write to it as appuser.
RUN mkdir -p /app/data && chown -R appuser:appuser /app
USER appuser
EXPOSE ${MCP_PORT:-8000}
CMD ["uv", "run", "python", "main.py"]