FROM python:3.11-slim AS base # Install uv (fast Python package manager) from official slim image. COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/ # System libs required by WeasyPrint at runtime. RUN apt-get update && apt-get install -y --no-install-recommends \ libpango-1.0-0 \ libpangocairo-1.0-0 \ libcairo2 \ libgdk-pixbuf-2.0-0 \ libffi-dev \ shared-mime-info \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # Copy lockfile + project metadata first to maximize Docker layer cache. COPY pyproject.toml uv.lock ./ COPY .python-version ./ # Install ONLY backend deps from the locked dependencies. --frozen ensures # we never resolve at build time; --no-dev keeps the image lean. RUN uv sync --frozen --no-dev --extra server # Now copy the actual sources. COPY src/ ./src/ # Uploads directory (mounted as a volume in production). RUN mkdir -p /app/uploads/images /app/uploads/pdfs /app/uploads/logos /app/uploads/reports EXPOSE 8000 # Entry point: run Alembic migrations then start Uvicorn through uv so # it uses the pinned interpreter and venv from `uv sync`. CMD ["sh", "-c", \ "uv run alembic -c src/backend/migrations/alembic.ini upgrade head && \ uv run uvicorn src.backend.main:app \ --host 0.0.0.0 --port 8000 --workers 4 \ --proxy-headers --forwarded-allow-ips='*'"]