# syntax=docker/dockerfile:1 # Stage 1: Install build tools and Python dependencies FROM python:3.13-slim AS builder COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ apt-get update && apt-get install -y --no-install-recommends \ build-essential \ gcc \ python3-dev \ libopencv-dev \ libmariadb-dev WORKDIR /app COPY requirements.txt ./ # Install dependencies into a venv using uv (10-25x faster than pip) RUN --mount=type=cache,target=/root/.cache/uv \ python -m venv /app/.venv && \ uv pip install --python /app/.venv/bin/python -r requirements.txt # Stage 2: Runtime system dependencies (runs in parallel with builder) FROM python:3.13-slim AS runtime-base RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \ apt-get update && apt-get install -y --no-install-recommends \ libglib2.0-0 \ tesseract-ocr \ tesseract-ocr-eng \ libmariadb3 \ curl # Stage 3: Test — runtime deps + venv + test dependencies + run tests FROM runtime-base AS test WORKDIR /app COPY --from=builder /app/.venv /app/.venv ENV PATH="/app/.venv/bin:$PATH" COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv RUN --mount=type=cache,target=/root/.cache/uv \ uv pip install --python /app/.venv/bin/python pytest pytest-asyncio pytest-xdist httpx aioresponses fakeredis COPY . . RUN pytest tests/ -x -q # Stage 4: Final image — combine venv from builder + runtime base FROM runtime-base AS production RUN adduser --system --no-create-home appuser WORKDIR /app # Copy the venv from the builder stage COPY --from=builder /app/.venv /app/.venv ENV PATH="/app/.venv/bin:$PATH" # Copy the application code COPY . . RUN chown -R appuser /app USER appuser EXPOSE 5001 HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=40s \ CMD curl -f http://localhost:5001/api/status || exit 1 CMD ["sh", "-c", "alembic upgrade head && uvicorn api.app:app --host 0.0.0.0 --port 5001 --no-server-header"]