# --- Base image -------------------------------------------------------------- FROM node:24-alpine AS base WORKDIR /app # (hilft manchen native Deps; Prisma nutzt linux-musl Binaries) RUN apk add --no-cache libc6-compat # --- Dependencies ------------------------------------------------------------ FROM base AS deps COPY package.json package-lock.json ./ COPY prisma ./prisma RUN npm ci # --- Builder ----------------------------------------------------------------- FROM base AS builder ENV NEXT_TELEMETRY_DISABLED=1 # Node-Module aus deps COPY --from=deps /app/node_modules ./node_modules # Projektquellen COPY . . # Build (empfohlen: Next standalone output, siehe Hinweis unten) RUN mkdir -p public RUN npm run build # --- Runner ------------------------------------------------------------------ FROM node:24-alpine AS runner ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 WORKDIR /app # optional: curl für Healthchecks RUN apk add --no-cache libc6-compat curl # App-User anlegen RUN addgroup -S app && adduser -S app -G app # Standalone + Assets COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static # COPY --from=builder /app/public ./public # nur falls du public/ nutzt # Prisma: Schema + Engines COPY --from=builder /app/prisma ./prisma COPY --from=deps /app/node_modules/.prisma ./node_modules/.prisma # separat persistentes DB-Verzeichnis (per Compose gemountet) RUN mkdir -p /data # ⬅︎ WICHTIG: Alles dem App-User übergeben, **nach** allen COPYs RUN chown -R app:app /data # Entrypoint COPY docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh USER app EXPOSE 3000 ENV PORT=3000 ENTRYPOINT ["/entrypoint.sh"] CMD ["node", "server.js"]