# The Context Vault web app: build the SPA, then serve it with nginx (+ proxy /api to the API).
# Part of the one-command self-hosted platform (see docker-compose.yml / docs/DEPLOY.md).
FROM node:20-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
# Vite inlines VITE_* at BUILD time (a static bundle has no runtime env), so whatever is passed
# here is baked into the shipped JS and readable by anyone who loads the page. The default is
# EMPTY on purpose: a build that passes no --build-arg produces a bundle with NO admin key
# (src/api.ts sends X-Admin-Key only when it is truthy) — that is what the published GHCR image
# and every production build get. Only the dev docker-compose.yml passes a value, for the local
# demo stack; a real deployment must not (see the `web` service comment there).
ARG VITE_ADMIN_KEY=""
ENV VITE_ADMIN_KEY=$VITE_ADMIN_KEY
RUN npm run build

FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Build-provenance stamp (stack-staleness tripwire) — the SPA bundle is baked into this image, so
# it goes stale exactly like the API. In the final stage so it never invalidates the npm build
# layer; `make stack-check` reads it back to warn when the running web container predates HEAD.
ARG GIT_SHA=unknown
LABEL org.opencontainers.image.revision=$GIT_SHA
EXPOSE 80
# nginx:alpine's default CMD runs the server in the foreground.
