# syntax=docker/dockerfile:1.7
#
# Goal:
# - "base" stage: slow, reusable, publishable (OS deps + pg client + uv + python deps)
# - "runtime" stage: fast, per-user (user/group ids, config files, entrypoint, permissions)
#
# Build base once and push:
#   docker buildx build --target base --build-arg PYTHON_VERSION=3.12.3 \
#     -t ghcr.io/<org>/<repo>/django-base:py3.12.3 --push .
#
# Normal users:
#   docker pull ghcr.io/<org>/<repo>/django-base:py3.12.3
#   docker build --build-arg BASE_IMAGE=ghcr.io/<org>/<repo>/django-base:py3.12.3 \
#     --build-arg APP_USER=alice --build-arg UID=1000 --build-arg GID=1000 --build-arg APP_GROUP=alice \
#     -t myapp:local .
#
# Compose can either:
# - use image: ghcr.io/.../django-base:... directly (no per-user build), OR
# - build runtime from this Dockerfile with BASE_IMAGE pointing to the published base.

ARG PYTHON_VERSION=3.12.3
ARG BASE_IMAGE=base

############################
# 1) PUBLISHABLE BASE LAYER
############################
FROM python:${PYTHON_VERSION}-slim AS base

ARG DEBUG=0
ENV PYTHONDONTWRITEBYTECODE=${DEBUG}
ENV PYTHONUNBUFFERED=1

# OS deps + pg client
RUN apt-get update && apt-get install -y --no-install-recommends \
      ca-certificates wget gnupg2 lsb-release sudo iputils-ping curl dos2unix cifs-utils \
    && install -d -m 0755 /etc/apt/keyrings \
    && wget -qO /etc/apt/keyrings/postgresql.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc \
    && echo "deb [signed-by=/etc/apt/keyrings/postgresql.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" \
         > /etc/apt/sources.list.d/pgdg.list \
    && apt-get update \
    && apt-get install -y --no-install-recommends postgresql-client-17 \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

# uv + python deps (cacheable)
RUN pip install --no-cache-dir uv

WORKDIR /app
COPY ./pyproject.toml /app/pyproject.toml
COPY ./uv.lock /app/uv.lock

# Copy source code at build time of the base (not necessary for end users)
COPY ./django_server/source_code_copy/ /app/src/alyx/

# Install deps into the system interpreter (fast reuse across users)
# Use BuildKit cache mounts for speed on rebuilds
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --all-groups

# Copy only the files that vary per deployment/user config
COPY ./django_server/entrypoint.sh /app/entrypoint.sh
COPY ./django_server/gunicorn.conf.py /app/gunicorn.conf.py

# Create directories that don't depend on user ids
RUN mkdir -p /app/uploaded/static /app/uploaded/media /mnt/external_data

############################
# 2) PER-USER RUNTIME LAYER
############################

FROM ${BASE_IMAGE} AS runtime

ARG APP_USER=%%PERMISSIONED_USERNAME%%
ARG UID=%%PERMISSIONED_UID%%
ARG GID=%%PERMISSIONED_GID%%
ARG APP_GROUP=%%PERMISSIONED_GROUPNAME%%

# Create group if not exists (this is the "per-user config" part)
RUN if ! getent group "${APP_GROUP}" >/dev/null; \
    then addgroup "${APP_GROUP}" --gid "${GID}"; \
    fi
# create user in that group
RUN adduser "${APP_USER}" \
    --disabled-password \
    --gecos "" \
    --shell "/sbin/nologin" \
    --home "/${APP_USER}"\
    --uid "${UID}" \
    --ingroup "${APP_GROUP}" 

# Copy only the files that vary per deployment/user config
COPY ./django_server/entrypoint.sh /app/entrypoint.sh
COPY ./django_server/gunicorn.conf.py /app/gunicorn.conf.py
COPY ./django_server/custom_settings.py /app/extra_configuration/custom_settings.py

# Entrypoint Permissions
RUN chown -R ${APP_USER}:${APP_GROUP} /app/entrypoint.sh  \
 && dos2unix -o /app/entrypoint.sh \
 && chmod +x /app/entrypoint.sh 

# Other file Permissions
RUN chown -R ${APP_USER}:${APP_GROUP} /app 
#  && chown -R ${APP_USER}:${APP_GROUP} /mnt/external_data \
#  && chmod -R 700 /mnt/external_data \
#  && echo "${APP_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# this last commented line can be usefull to debug permission problems. 
# It effectively makes the user run any command as root. Do not use in prod.

USER ${APP_USER}
WORKDIR /app
EXPOSE 80
CMD ["./entrypoint.sh"]
