FROM node:lts-trixie-slim AS base

# Install dependencies only when needed
FROM base AS deps
WORKDIR /app

RUN apt-get update && apt-get install -y --no-install-recommends \
  python3 make g++ \
  && rm -rf /var/lib/apt/lists/*

# Install dependencies based on the preferred package manager
COPY overlord/package.json overlord/yarn.lock* overlord/package-lock.json* overlord/pnpm-lock.yaml* ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY /overlord ./

RUN \
  if [ -f yarn.lock ]; then yarn run build; \
  elif [ -f package-lock.json ]; then npm run build; \
  elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
  else echo "Lockfile not found." && exit 1; \
  fi


FROM python:3.14-slim AS runner
LABEL maintainer="Amritanshu <docker@tanshu.com>"

RUN apt update \
  && apt install -y --no-install-recommends curl \
  && rm -rf /var/lib/apt/lists/* \
  apt update && \
  apt install -y locales && \
  sed --in-place --expression='s/# en_IN UTF-8/en_IN UTF-8/' /etc/locale.gen && \
  dpkg-reconfigure --frontend=noninteractive locales \
  && rm -rf /var/lib/apt/lists/* 

ENV LANG=en_IN
ENV LC_ALL=en_IN

# Install uv
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# Compile bytecode
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#compiling-bytecode
ENV UV_COMPILE_BYTECODE=1

# Disable development dependencies
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-a-project
ENV UV_NO_DEV=1

# uv Cache
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#caching
ENV UV_LINK_MODE=copy
WORKDIR /app/

# Place executables in the environment at the front of the path
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#using-the-environment
ENV PATH="/app/.venv/bin:$PATH"

# Install dependencies
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
RUN --mount=type=cache,target=/root/.cache/uv \
  --mount=type=bind,source=brewman/uv.lock,target=uv.lock \
  --mount=type=bind,source=brewman/pyproject.toml,target=pyproject.toml \
  uv sync --locked --no-install-project

COPY /brewman ./
COPY --from=builder /frontend/browser /app/static

# Sync the project
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
RUN --mount=type=cache,target=/root/.cache/uv \
  --mount=type=bind,source=brtewman/uv.lock,target=uv.lock \
  --mount=type=bind,source=brewman/pyproject.toml,target=pyproject.toml \
  uv sync --locked

ENV PYTHONPATH=/app
EXPOSE 80

RUN chmod 777 /app/docker-entrypoint.sh \
  && ln -s /app/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh \
  && ln -s /app/docker-entrypoint.sh /
ENTRYPOINT ["docker-entrypoint.sh"]

# at the end of your Dockerfile, before CMD or after EXPOSE
# Kill the main process if the healthcheck fails. This will kill the container and restart policy can restart it.
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
  CMD curl -fsS http://localhost/health  || kill -s 15 1

CMD ["gunicorn", "brtewman.main:app", "--worker-class", "uvicorn.workers.UvicornWorker", "--config", "./gunicorn.conf.py", "--log-config", "./logging.conf"]
