# Multi-stage image for the sengol-api server used by docker-compose.
# Stays Apache-2.0 — no proprietary base or wheels.
#
# Base image matches CI's interpreter (Python 3.11) so what we test is what we
# ship. Bump CI in lockstep if you change this.
#
# Stage 1 (console) builds the Console SPA with Node so the runtime image
# ships it inside the installed package (sengol/console_static/ — see
# console/vite.config.ts outDir). Without this stage the Console is
# unreachable in the shipped image, even though the code to serve it exists.

FROM node:20-slim AS console

WORKDIR /app/console

# Install deps first so the layer cache holds across source-only changes.
COPY console/package.json console/package-lock.json ./
RUN npm ci

COPY console/ ./
# Output lands at /app/sengol/console_static per vite.config.ts's
# `build.outDir: "../sengol/console_static"` (relative to console/).
RUN npm run build


FROM python:3.11-slim AS runtime

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    UV_SYSTEM_PYTHON=1

WORKDIR /app

# uv first so the layer cache holds across SDK code changes.
RUN pip install --no-cache-dir uv

# Copy metadata + source. uv reads README.md when resolving the package, so
# the .dockerignore must keep it in the build context.
COPY pyproject.toml uv.lock README.md alembic.ini ./
COPY alembic ./alembic
COPY sengol ./sengol

# Built Console assets — must land here BEFORE `uv pip install --system .` so
# they're picked up by the package build (console_static/ is gitignored;
# pyproject.toml's [tool.hatch.build.targets.wheel] artifacts entry
# force-includes it despite that).
COPY --from=console /app/sengol/console_static ./sengol/console_static

# Install dependencies + the package itself into the SYSTEM interpreter so
# the `uvicorn` entrypoint below resolves the right environment without
# requiring `uv run` at runtime.
RUN uv pip install --system --no-cache ".[otlp,server,reports,model]" \
    && uv pip install --system --no-cache "uvicorn[standard]"

EXPOSE 8080

# Drop privileges. The image runs as a non-root, non-login user.
RUN useradd --uid 10001 --user-group --no-create-home --shell /usr/sbin/nologin sengol
USER sengol

HEALTHCHECK --interval=15s --timeout=3s --start-period=10s --retries=3 \
    CMD python -c "import urllib.request, sys; \
sys.exit(0 if urllib.request.urlopen('http://localhost:8080/health', timeout=2).status == 200 else 1)"

CMD ["uvicorn", "sengol.api:app", "--host", "0.0.0.0", "--port", "8080"]
