Files
XQKqueue/docs/superpowers/specs/2026-07-14-web-container-design.md

2.4 KiB

Web Container and Kubernetes Routing Design

Goal

Provide a production container image for the React/Vite frontend so the existing Jenkins command docker build ./web succeeds and the application works correctly behind Kubernetes Ingress.

Architecture

The web image uses a multi-stage build:

  1. A Node.js 22 Alpine stage installs the locked pnpm dependencies and runs the existing pnpm build script.
  2. An Nginx Alpine stage serves the generated dist directory on port 80.

The web container serves static assets only. It does not proxy API traffic and therefore has no dependency on Kubernetes service names.

Request Routing

Kubernetes Ingress exposes the frontend and API on one origin:

  • /api/* routes to the API Service on port 8080.
  • All other paths route to the web Service on port 80.

This matches the frontend's existing relative /api requests and keeps session cookies same-origin. No CORS configuration or production VITE_API_BASE_URL is required.

Nginx Behavior

Nginx serves files from the Vite build output. Requests that do not match a real file fall back to /index.html, allowing React Router routes such as /admin, /staff, /visitor/:token, and /display/:token to survive direct navigation and page refreshes.

Static files receive normal Nginx content types. The container runs in the foreground using the base image's standard entrypoint and listens on port 80.

Build Inputs

The Docker build context remains ./web. Dependency manifests are copied before application sources so dependency installation can be cached. Installation uses the lockfile in frozen mode to make Jenkins builds reproducible.

A .dockerignore excludes node_modules, dist, coverage output, test reports, logs, and local editor files from the build context.

Verification

Verification covers:

  • pnpm build completes successfully.
  • The Dockerfile parses and the web image builds when the configured Docker registry is available.
  • The image contains the generated frontend files and Nginx SPA fallback configuration.
  • A container request to / returns the application entry page.
  • A request to a client-side route such as /admin also returns the application entry page.

Kubernetes manifests and Ingress resources are outside this change because they are not present in this repository. The required path mapping is documented above for the deployment configuration.