FROM oven/bun:alpine AS deps WORKDIR /app COPY package.json bun.lock ./ RUN bun install --frozen-lockfile --production # ───────────────────────────────────────────── FROM oven/bun:alpine AS builder WORKDIR /app COPY package.json bun.lock ./ RUN bun install --frozen-lockfile COPY . . # PUBLIC_API_BASE_URL is baked at build time if using $env/static/public. # If using $env/dynamic/public, remove the ARG/ENV below and pass it at runtime. ARG PUBLIC_API_BASE_URL=https://api.marktvogt.de ENV PUBLIC_API_BASE_URL=$PUBLIC_API_BASE_URL RUN bun run build # ───────────────────────────────────────────── FROM node:22-alpine WORKDIR /app COPY --from=builder /app/build ./build COPY --from=deps /app/node_modules ./node_modules COPY --from=builder /app/package.json . # node:22-alpine already ships nobody at UID 65534 — matches podSecurityContext.runAsUser USER nobody:nobody # ORIGIN is required by adapter-node for CSRF protection. # Must match the public-facing URL exactly (set via k8s ConfigMap). ENV PORT=3000 HOST=0.0.0.0 NODE_ENV=production EXPOSE 3000 CMD ["node", "build"]