Browsers disable crypto.subtle on non-localhost HTTP. The frontend server now
generates a self-signed TLS cert at startup and serves over HTTPS by default
(FRONTEND_TLS=true). FRONTEND_TLS=0 disables it for localhost dev.
Added axum-server (tls-rustls) + rcgen deps to the frontend-server crate.
A dedicated Rust/Axum binary (web/frontend-server/) that:
- Serves the built Vite SPA bundle from dist/ via tower-http ServeDir
- Falls back to index.html for SPA routing (deep links work)
- Reverse-proxies /api/* to the backend container (same-origin, no CORS)
- Listens on port 8080 (configurable via FRONTEND_PORT)
Dockerfile (web/normogen-web/Dockerfile): 3-stage build:
1. Node: npm ci + npm run build -> dist/
2. Rust: cargo build --release the frontend-server binary
3. Runtime: debian-slim + binary + dist/
docker-compose.yml: new 'frontend' service on :8080, depends on backend healthy,
proxies to http://backend:6500. Independently scalable (run N replicas behind
a load balancer).
Architecture:
Browser -> :8080 (frontend container)
/api/* -> proxy -> backend:6500
/* -> static dist/ (SPA)