FROM python:3.14-slim

# Copy uv helper binary from the uv image so we can manage venvs and pip
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Install build deps required for common Python packages and netcat for health wait
RUN apt-get update \
     && apt-get install -y --no-install-recommends \
         build-essential \
         gcc \
         git \
         libpq-dev \
         pkg-config \
         libcairo2-dev \
         # some distributions provide libgdk-pixbuf under the xlib name
         libgdk-pixbuf-xlib-2.0-0 \
         libgdk-pixbuf-xlib-2.0-dev \
         libjpeg-dev \
         zlib1g-dev \
         wget \
         ca-certificates \
         netcat-openbsd \
     && rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app

# Install python deps into a uv-managed venv for reproducible builds
COPY requirements.txt /usr/src/app/
# Prebuild wheels into /wheels so compiled artifacts are cached in a layer.
# This speeds rebuilds when `requirements.txt` hasn't changed. The first build
# still needs to compile any packages without prebuilt wheels.
RUN mkdir -p /wheels \
    && python -m venv /tmp/venvbuild \
    && /tmp/venvbuild/bin/pip install --upgrade pip setuptools wheel \
    && /tmp/venvbuild/bin/pip wheel --wheel-dir=/wheels -r requirements.txt \
    && rm -rf /tmp/venvbuild

# Create the final uv-managed venv and install from the cached wheels where
# possible. Using `--no-index --find-links=/wheels` makes pip prefer the
# prebuilt wheels, avoiding recompilation.
RUN uv venv /opt/venv \
    && export VIRTUAL_ENV=/opt/venv \
    && export PATH="/opt/venv/bin:$PATH" \
    && uv pip install --upgrade pip setuptools wheel \
    && uv pip install --no-index --find-links=/wheels -r requirements.txt

# Ensure the runtime environment uses the uv-managed venv by default.
# This persists the venv into image ENV so `python` and `gunicorn` point
# to the venv-installed binaries at container start.
ENV VIRTUAL_ENV=/opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Create non-root user before copying files so we can use Docker's
# `--chown` flag during COPY and avoid an expensive recursive `chown -R`.
RUN useradd -m appuser

# Create directory for application logs and ensure ownership is correct.
# Do this as root before switching to `appuser` so the directory exists
# and can be mounted by the dev compose override.
RUN mkdir -p /var/log/rad \
    && chown -R appuser:appuser /var/log/rad

# Copy project files into image and set ownership during copy (faster than
# a separate `chown -R` step). This keeps layer reuse efficient.
COPY --chown=appuser:appuser . /usr/src/app

# Ensure the venv is usable by the non-root user; chown only the venv path
# (much smaller than the whole project tree) to avoid a long recursive chown.
RUN chown -R appuser:appuser /opt/venv

# Make the entrypoint executable (some files in the repo may not have the
# executable bit set). Do this as root before switching to the app user.
RUN [ -f /usr/src/app/entrypoint.sh ] && chmod +x /usr/src/app/entrypoint.sh || true
USER appuser

ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
