# syntax=docker/dockerfile:1.7
# Multi-arch (amd64 + arm64) image for juan.
# - Stage 1 builds the .venv with uv.
# - Stage 2 ships only the venv + source under a non-root user.

FROM python:3.13-slim AS builder

ENV UV_LINK_MODE=copy \
    UV_COMPILE_BYTECODE=1 \
    UV_PROJECT_ENVIRONMENT=/opt/venv

# Install uv. Pin so reproducible builds don't drift.
COPY --from=ghcr.io/astral-sh/uv:0.7 /uv /uvx /usr/local/bin/

WORKDIR /app

# Layer 1: manifests (cacheable).
COPY pyproject.toml uv.lock ./

# Layer 2: project source + install into /opt/venv (see UV_PROJECT_ENVIRONMENT above).
COPY reviewer ./reviewer
COPY server ./server
COPY juan ./juan
COPY cli.py ./cli.py
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-dev \
    && test -x /opt/venv/bin/juan \
    && test -x /opt/venv/bin/python


FROM python:3.13-slim AS runtime

ENV PATH="/opt/venv/bin:$PATH" \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    JUAN_DB=/app/data/juan.sqlite3

# Run as a non-root user for defence in depth.
RUN groupadd --system app \
    && useradd --system --gid app --create-home --shell /usr/sbin/nologin app

WORKDIR /app

# Venv from builder (always /opt/venv — not .venv — because UV_PROJECT_ENVIRONMENT is set).
COPY --from=builder /opt/venv /opt/venv
COPY --from=builder /app /app
RUN test -x /opt/venv/bin/juan

# Persistent data lives under /app/data; mount a volume on top of it.
RUN mkdir -p /app/data && chown -R app:app /app

USER app

EXPOSE 8000

# Lightweight container healthcheck against /live (process up).
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD python -c "import urllib.request, sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8000/live', timeout=2).status == 200 else 1)"

# juan serve picks up SERVER_HOST / SERVER_PORT from env.
CMD ["juan", "serve"]
