FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS base ENV UV_COMPILE_BYTECODE=1 ENV UV_LINK_MODE=copy ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 WORKDIR /app FROM base AS builder COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ COPY pyproject.toml ./ RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --no-install-project --no-editable COPY . . RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --no-editable # Development target FROM base AS development RUN groupadd --gid 1000 app \ && useradd --uid 1000 --gid app --shell /bin/bash --create-home app COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ USER app EXPOSE 8000 CMD ["/bin/sh", "-c", "if [ ! -d .venv ]; then uv sync; fi && uv run uvicorn src.main:app --host 0.0.0.0 --port 8000 --reload"] # Production target FROM base AS production COPY --from=builder --chown=app:app /app /app RUN groupadd --gid 1000 app \ && useradd --uid 1000 --gid app --shell /bin/bash --create-home app USER app EXPOSE 8000 HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ CMD ["/app/.venv/bin/python", "-c", "import requests; requests.get('http://localhost:8000/health')"] CMD ["/app/.venv/bin/uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"] # Worker development target FROM development AS worker-development CMD ["/bin/sh", "-c", "if [ ! -d .venv ]; then uv sync; fi && uv run python -m src.services.procrastinate_hot_reload"] # Worker production target FROM production AS worker-production CMD ["/app/.venv/bin/procrastinate", "worker"]