# syntax=docker/dockerfile:1 FROM python:3.12-slim AS builder RUN pip install --no-cache-dir uv WORKDIR /app COPY pyproject.toml uv.lock ./ # Split into two syncs so dependency installation caches independently of source changes: this # first one installs only dependencies (--no-install-project), so touching velodrome/ doesn't # invalidate this layer. RUN uv sync --frozen --no-install-project --no-dev COPY velodrome ./velodrome COPY alembic ./alembic COPY alembic.ini ./ # Now install the project itself into the same venv. RUN uv sync --frozen --no-dev FROM python:3.12-slim AS runtime RUN groupadd --system velodrome && useradd --system --gid velodrome --create-home velodrome WORKDIR /app COPY --from=builder /app /app ENV PATH="/app/.venv/bin:$PATH" USER velodrome EXPOSE 8000 # Migrations run as an explicit step before this in deploy.yml (see docs/PLAN.md) — never from # the entrypoint, so a failed migration fails the deploy visibly instead of crash-looping here. CMD ["uvicorn", "velodrome.app:app", "--host", "0.0.0.0", "--port", "8000"]