feat(server): serve the client-only build with Bun

Angular's server build needs Node loader hooks that Bun does not apply,
and every route is client-rendered, so Angular now builds a client-only
bundle and a small Bun.serve server delivers it: hashed assets with the
one-year cache, index.html revalidated, extension-less routes falling
back to index.html, missing assets 404, traversal and malformed paths
rejected, and other methods 405. Express, @angular/ssr and the unused
hydration provider are removed. Both Docker stages use the pinned
oven/bun:1.4.3-alpine image without Node, and the health checks use
Bun's fetch.

Refs #292

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nessarandClaude Opus 5.5 committed 2026-10-17 13:50:05 +02:00
1 parent 94d57add2c
commit f74d744f9b
15 files changed
+260 -306

No files matched your search

+11 -29
View File
@@ -1,48 +1,30 @@
# Stage 1: Build the Angular application
FROM oven/bun:alpine AS builder
# Stage 1: Build the Angular application and the Bun static server
FROM oven/bun:1.4.3-alpine@sha256:629e17411f1f129dbec3af78d5af9c9f2a937435c80349437206c6b0b7422373 AS builder
# Install nodejs to support Angular prerendering worker threads
RUN apk add --no-cache nodejs
# Set working directory
WORKDIR /app
# Copy package files
COPY package.json bun.lock* ./
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
# Install dependencies
RUN bun install
# Copy source code
COPY . .
# Build the application for production
RUN bun run build
# --bun makes Angular's Node-shebang CLI run on Bun instead of a Node on PATH
RUN bun --bun run build
# Stage 2: Production image
FROM oven/bun:alpine AS production
FROM oven/bun:1.4.3-alpine@sha256:629e17411f1f129dbec3af78d5af9c9f2a937435c80349437206c6b0b7422373 AS production
# Set working directory
WORKDIR /app
# Copy package files
COPY package.json bun.lock* ./
# Install only production dependencies
RUN bun install --production
# Copy built application from builder stage
# The server is a self-contained Bun bundle that serves the browser build, so
# the runtime has no dependencies to install.
COPY --from=builder /app/dist ./dist
# Set environment to production
ENV NODE_ENV=production
# Expose port (default Express port)
EXPOSE 4000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD bun -e "require('http').get('http://localhost:4000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
CMD bun -e "fetch('http://localhost:' + (process.env.PORT || 4000) + '/').then(r => process.exit(r.ok ? 0 : 1), () => process.exit(1))"
# Start the application
CMD ["bun", "run", "dist/vac-optimizer/server/server.mjs"]
CMD ["bun", "dist/vac-optimizer/server/server.js"]