40 lines
1.2 KiB
Docker
40 lines
1.2 KiB
Docker
# Multi-stage build for TOD Frontend
|
|
# Stage 1: build — Node.js build environment
|
|
FROM node:20-alpine AS builder
|
|
|
|
# Cap Node.js heap to 512 MB so tsc + vite build don't OOM a low-RAM server.
|
|
# Vite's bundler defaults to using all available heap; on a 2-4 GB machine that
|
|
# competes directly with the Go and Python builds happening in parallel.
|
|
ENV NODE_OPTIONS="--max-old-space-size=1024"
|
|
|
|
WORKDIR /build
|
|
|
|
# Copy package files first (layer cache optimization)
|
|
COPY frontend/package.json frontend/package-lock.json* ./
|
|
|
|
# Install dependencies
|
|
RUN npm ci --ignore-scripts
|
|
|
|
# Copy frontend source and build
|
|
# Note: skip tsc type-check in Docker build (esbuild handles transpilation).
|
|
# Run `npm run build` locally or in CI for full type-checking.
|
|
COPY frontend/ .
|
|
RUN npx vite build
|
|
|
|
# Stage 2: runtime — nginx serving static SPA files
|
|
FROM nginx:alpine AS runtime
|
|
|
|
# Remove default nginx config
|
|
RUN rm /etc/nginx/conf.d/default.conf
|
|
|
|
# Custom nginx config for SPA routing (all routes -> index.html)
|
|
COPY infrastructure/docker/nginx-spa.conf /etc/nginx/conf.d/default.conf
|
|
|
|
# Copy built assets from builder stage
|
|
COPY --from=builder /build/dist /usr/share/nginx/html
|
|
|
|
# nginx runs as nginx user (non-root by convention)
|
|
EXPOSE 80
|
|
|
|
CMD ["nginx", "-g", "daemon off;"]
|