# ── Stage 1: builder ─────────────────────────────────────────────── FROM node:18-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ COPY prisma ./prisma/ RUN npm ci --no-audit --no-fund RUN npx prisma generate # ── Stage 2: production ──────────────────────────────────────────── FROM node:18-alpine AS production ENV NODE_ENV=production WORKDIR /app # Non-root user RUN addgroup -S appgroup && adduser -S appuser -G appgroup # Production-only npm dependencies COPY package.json package-lock.json ./ RUN npm ci --omit=dev --no-audit --no-fund # Copy generated Prisma client from builder COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma # Copy prisma CLI so init container can run 'prisma migrate deploy' COPY --from=builder /app/node_modules/prisma ./node_modules/prisma COPY --from=builder /app/node_modules/.bin/prisma ./node_modules/.bin/prisma # Copy app source + Prisma schema/migrations COPY src ./src COPY prisma ./prisma # Temp uploads dir (emptyDir volume mounted here in k8s) RUN mkdir -p uploads USER appuser EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD wget -qO- http://localhost:3000/health || exit 1 CMD ["node", "src/server.js"]