FROM node:24-slim RUN apt-get update && apt-get install -y openssl && rm -rf /var/lib/apt/lists/* RUN corepack enable && corepack prepare pnpm@10.10.0 --activate WORKDIR /app/frontend COPY frontend/package.json frontend/pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile || (echo "WARN: frozen-lockfile failed, falling back to pnpm install" && pnpm install) COPY frontend/ . # Generate self-signed cert for HTTPS (required for WebAuthn/crypto.subtle) RUN openssl req -x509 -newkey rsa:2048 -keyout /tmp/key.pem -out /tmp/cert.pem \ -days 365 -nodes -subj '/CN=frontend' # Allow Docker internal hostnames (e.g. "frontend") to pass Vite's host check. # Configure HTTPS with self-signed cert for secure context (WebAuthn/crypto.subtle). # Proxy API paths to the worker to avoid mixed-content (HTTPS->HTTP) blocking. RUN mv vite.config.js vite.config.original.js && \ echo 'import config from "./vite.config.original.js";\ import fs from "fs";\ const workerTarget = process.env.VITE_WORKER_URL || "http://worker:8787";\ config.server = {\ ...config.server,\ allowedHosts: true,\ https: {\ key: fs.readFileSync("/tmp/key.pem"),\ cert: fs.readFileSync("/tmp/cert.pem"),\ },\ proxy: {\ "/api": { target: workerTarget, changeOrigin: true },\ "/admin": { target: workerTarget, changeOrigin: true },\ "/user_api": { target: workerTarget, changeOrigin: true },\ "/open_api": { target: workerTarget, changeOrigin: true },\ "/external": { target: workerTarget, changeOrigin: true },\ "/health_check": { target: workerTarget, changeOrigin: true },\ },\ };\ export default config;' > vite.config.js # Empty VITE_API_BASE so frontend uses same-origin (proxied through Vite) ENV VITE_API_BASE= EXPOSE 5173 CMD ["pnpm", "exec", "vite", "--port", "5173", "--host", "0.0.0.0"]