# syntax=docker/dockerfile:1.20 ARG PY_IMAGE=python:3.12-slim # Stage 1: Base Builder FROM ${PY_IMAGE} AS base-builder RUN apt-get update && \ apt-get install -y --no-install-recommends \ curl git \ && rm -rf /var/lib/apt/lists/* COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ UV_COMPILE_BYTECODE=1 \ UV_LINK_MODE=copy \ UV_PROJECT_ENVIRONMENT=/opt/venv COPY pyproject.toml uv.lock ./ # Stage 2: Backend Builder FROM base-builder AS backend-builder COPY ./src ./src RUN uv sync --frozen --no-dev --no-cache --group backend # Stage 3: ML Builder FROM base-builder AS ml-builder COPY ./src ./src RUN uv sync --frozen --no-dev --no-cache --group ml RUN uv add prometheus-fastapi-instrumentator # Stage 4: Backend Runtime FROM ${PY_IMAGE} AS runtime RUN apt-get update && \ apt-get install -y --no-install-recommends \ curl \ && rm -rf /var/lib/apt/lists/* ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PATH="/opt/venv/bin:$PATH" \ PYTHONPATH="/app:$PYTHONPATH" WORKDIR /app COPY --from=backend-builder /opt/venv /opt/venv COPY ./src/ ./ EXPOSE 8080 CMD [ "/opt/venv/bin/web_api_cli", "/app/config.toml" ] # Stage 5: ML Runtime FROM ${PY_IMAGE} AS ml RUN apt-get update && \ apt-get install -y --no-install-recommends \ curl \ && rm -rf /var/lib/apt/lists/* ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PATH="/opt/venv/bin:$PATH" \ PYTHONPATH="/app:$PYTHONPATH" WORKDIR /app COPY --from=ml-builder /opt/venv /opt/venv COPY ./src/ ./ EXPOSE 8081 CMD [ "/opt/venv/bin/ml_api_cli", "/app/config.toml" ] # Stage 6: Testing FROM base-builder AS tests ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PATH="/opt/venv/bin:$PATH" \ PYTHONPATH="/app:$PYTHONPATH" WORKDIR /app COPY ./src ./src COPY ./tests ./tests RUN uv sync --group backend --group tests --frozen --no-cache --no-dev RUN mkdir -p /app/cov && mkdir /app/cov/html CMD [ "sh", "-c", "coverage run --source=src -m pytest -v && coverage report > /app/cov/coverage.txt && coverage xml -o /app/cov/coverage.xml && coverage html -d /app/cov/html" ] # Stage 7: Migrations FROM base-builder AS migrations ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PATH="/opt/venv/bin:$PATH" \ PYTHONPATH="/app:$PYTHONPATH" WORKDIR /app RUN mkdir -p ./src/template_project COPY ./src ./src COPY ./tests ./tests COPY ./alembic.ini ./ RUN uv sync --group backend --group migrations --frozen --no-cache --no-dev CMD [ "alembic", "upgrade", "head" ]