# second-brain web container — review/dashboard UI only.
#
# Slim by design: this image runs `uvicorn` against second_brain.web.app.
# It does NOT need ffmpeg, the claude CLI, faster-whisper, or any GPU
# tooling. Extraction runs on the dev host's CLI; transcription runs on
# the tower. The web role is just "FastAPI + psycopg + Jinja templates".

FROM python:3.12-slim AS base

ENV PYTHONUNBUFFERED=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1 \
    UV_LINK_MODE=copy \
    UV_PROJECT_ENVIRONMENT=/app/.venv

# uv is fetched as a static binary from its official image so we don't
# pull a full python stack to install it.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/

# `git` is needed at *build* time because pyproject.toml pins
# embedding-chunking to a Gitea VCS source. `ca-certificates` so the
# https handshake validates. Slim image to clean up apt afterwards.
RUN apt-get update \
 && apt-get install -y --no-install-recommends git ca-certificates \
 && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Project metadata first so the layer cache survives source edits.
COPY pyproject.toml uv.lock ./

# `--frozen` enforces lockfile parity. `--no-dev` excludes pytest/ruff.
# `--no-install-project` so we don't try to install the (not-yet-copied)
# source tree in this layer.
RUN uv sync --frozen --no-dev --no-install-project

# Source + runtime config. config/settings.toml.example is committed; a
# real settings.toml gets bind-mounted in by compose at runtime.
COPY src/ ./src/
COPY config/ ./config/
COPY alembic/ ./alembic/
COPY alembic.ini ./alembic.ini

# Now install the project itself into the venv (puts the `second-brain`
# console script + the second_brain package on PATH).
RUN uv sync --frozen --no-dev

# Drop privileges. The image doesn't write to the host bind-mounts; the
# settings.toml mount is read-only.
RUN useradd --uid 1000 --create-home --shell /sbin/nologin app \
 && chown -R app:app /app
USER app

EXPOSE 8000

# Bind to all interfaces inside the container — the host port publish
# decides who can reach it from outside. `--proxy-headers` lets Traefik
# (off-box on 10.0.11.20) forward X-Forwarded-* correctly.
CMD ["/app/.venv/bin/uvicorn", \
     "second_brain.web.app:app", \
     "--host", "0.0.0.0", \
     "--port", "8000", \
     "--proxy-headers", \
     "--forwarded-allow-ips=*"]
