feat: separate frontend container (Axum static serving + API proxy)

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)
This commit is contained in:
goose 2026-07-05 11:24:19 -03:00
parent 43a427e2dd
commit 1b5c1e2a06
4 changed files with 227 additions and 0 deletions

View file

@ -0,0 +1,54 @@
# Multi-stage Dockerfile for the Normogen frontend server.
#
# Stage 1: Build the Vite SPA bundle.
# Stage 2: Build the Axum frontend-server binary.
# Stage 3: Slim runtime with the binary + static files.
# ============================================================================
# Stage 1: Node — build the Vite SPA
# ============================================================================
FROM node:20-slim AS node-builder
WORKDIR /app
# Copy package files and install deps.
COPY package.json package-lock.json ./
RUN npm ci
# Copy the source and build.
COPY . .
RUN npm run build
# ============================================================================
# Stage 2: Rust — build the frontend-server binary
# ============================================================================
FROM rust:latest AS rust-builder
WORKDIR /server
# Copy the frontend-server crate.
COPY frontend-server/ ./
# Build release.
RUN cargo build --release
# ============================================================================
# Stage 3: Runtime — slim image with binary + static files
# ============================================================================
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy the frontend-server binary.
COPY --from=rust-builder /server/target/release/normogen-frontend-server /app/frontend-server
# Copy the built static files.
COPY --from=node-builder /app/dist /app/dist
EXPOSE 8080
CMD ["./frontend-server"]