# ── Stage 1: build ──────────────────────────────────────────────────────────── FROM node:20-alpine AS builder # Create non-root user (UID/GID 1001) RUN addgroup -g 1001 appuser && adduser -u 1001 -G appuser -s /bin/sh -D appuser WORKDIR /app RUN chown appuser:appuser /app USER appuser COPY --chown=appuser:appuser package.json package-lock.json* ./ RUN npm ci COPY --chown=appuser:appuser . . RUN npm run build # ── Stage 2: serve with nginx (unprivileged, UID 101) ───────────────────────── FROM nginxinc/nginx-unprivileged:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 8080