3.8 KiB
Web Container Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add a production frontend image so docker build -t xqkqueue-web:<tag> ./web succeeds and React client-side routes work behind Kubernetes Ingress.
Architecture: A Node.js 22 Alpine build stage installs locked pnpm dependencies and creates the Vite dist output. An Nginx Alpine runtime stage serves that output on port 80 and falls back to index.html for client-side routes; Kubernetes Ingress routes /api/* directly to the API Service.
Tech Stack: Node.js 22, pnpm 10.17.0, Vite 7, Nginx 1.28 Alpine, Docker
Global Constraints
- Keep the Docker build context as
./web. - Serve the frontend on container port 80.
- Do not proxy
/apiin the web container; Kubernetes Ingress owns API routing. - Use
pnpm install --frozen-lockfilefor reproducible dependency resolution. - Do not modify frontend business code or add Kubernetes manifests.
Task 1: Production web image and SPA server
Files:
- Create:
web/Dockerfile - Create:
web/nginx.conf - Create:
web/.dockerignore
Interfaces:
-
Consumes:
web/package.json,web/pnpm-lock.yaml, the Vite source tree, and a Kubernetes Ingress that sends non-API paths to port 80. -
Produces: a static Nginx image exposing port 80, with Vite assets in
/usr/share/nginx/htmland SPA fallback for unknown non-file paths. -
Step 1: Reproduce the missing build definition
Run from the repository root:
docker build -t xqkqueue-web:verify ./web
Expected before implementation: FAIL with failed to read dockerfile: open Dockerfile: no such file or directory.
- Step 2: Add the multi-stage Dockerfile
Create web/Dockerfile:
FROM node:22-alpine AS build
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@10.17.0 --activate
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM nginx:1.28-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
- Step 3: Add SPA-aware Nginx configuration
Create web/nginx.conf:
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
- Step 4: Exclude local and generated files from the build context
Create web/.dockerignore:
node_modules
dist
coverage
playwright-report
test-results
*.log
*.tsbuildinfo
.DS_Store
.idea
.vscode
- Step 5: Verify the existing production frontend build
Run:
pnpm --dir web build
Expected: TypeScript checks and the Vite production build finish with exit code 0 and write web/dist/index.html.
- Step 6: Build the container image
Run:
docker build --progress=plain -t xqkqueue-web:verify ./web
Expected: exit code 0, including successful pnpm install --frozen-lockfile, pnpm build, and Nginx runtime stages.
- Step 7: Verify root and client-side route responses
Run:
docker run --rm -d --name xqkqueue-web-verify -p 18080:80 xqkqueue-web:verify
curl --fail http://127.0.0.1:18080/
curl --fail http://127.0.0.1:18080/admin
docker stop xqkqueue-web-verify
Expected: both requests return the Vite application HTML with HTTP 200, and the verification container stops cleanly.
- Step 8: Review and commit the implementation
Run:
git diff --check
git status --short
git add web/Dockerfile web/nginx.conf web/.dockerignore
git commit -m "build: add frontend container image"
Expected: only the three intended web container files are committed.