diff --git a/Dockerfile b/Dockerfile index 4c5e8c9..ffe1e79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,10 +12,27 @@ RUN npm run build FROM python:3.14-slim AS runtime WORKDIR /app -COPY pyproject.toml . -COPY src/ src/ +# Installed from uv.lock, exactly like CI (issue #2194). This used to be +# `COPY pyproject.toml .` + `pip install .`, which never even copied the lock: +# the shipped image resolved its own dependency set, so CI could be green on one +# set of versions while the published image ran another. On 2026-07-28 that +# class of drift turned `main` red when mcp 2.0.0 shipped mid-session. RUN --mount=type=cache,target=/root/.cache/pip \ - pip install . + pip install --no-cache-dir uv + +# Dependencies before source, so the expensive layer is cached on every build +# that doesn't change the lock. +COPY pyproject.toml uv.lock ./ +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev --no-install-project + +COPY src/ src/ +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --locked --no-dev + +# uv sync installs into a project venv rather than the system interpreter, so +# alembic and hypercorn in CMD have to be found there. +ENV PATH="/app/.venv/bin:$PATH" COPY --from=build-frontend /build/dist/ src/scribe/static/ COPY alembic.ini .