# syntax=docker/dockerfile:1 # # Zwei Images aus einem Build: # docker build --target runner -t /artista-modelcamp: . # docker build --target tools -t /artista-modelcamp-tools: . # # runner: der Next.js-Server (standalone), sonst nichts. # tools: Prisma-CLI + tsx fuer die Migration (initContainer im App-Deployment), # den Worker (CronJob) und `admin:create`. # Beide IMMER mit demselben Tag bauen und ausrollen — sie teilen das # Datenbankschema. FROM node:22.23.2-alpine3.24 AS base # openssl: die Prisma-Schema-Engine (migrate deploy) braucht libssl unter # Alpine; Prisma waehlt anhand der installierten Version die passende Binary. RUN apk add --no-cache openssl && corepack enable WORKDIR /app ENV NEXT_TELEMETRY_DISABLED=1 # --- Abhaengigkeiten -------------------------------------------------------- FROM base AS deps COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ # postinstall (prisma generate) braucht das Schema, das erst im builder # vorliegt; generiert wird dort ausdruecklich. RUN pnpm install --frozen-lockfile --ignore-scripts # --- Build ------------------------------------------------------------------ FROM base AS builder COPY --from=deps /app/node_modules ./node_modules COPY . . # Die Installation oben lief mit --ignore-scripts. Die Schema-Engine fuer # "prisma migrate deploy" laedt aber erst das postinstall von @prisma/engines # herunter — ohne diesen Schritt scheitert der Migrations-initContainer. # Zur Build-Zeit wird keine Datenbank und kein Secret benoetigt. RUN pnpm rebuild @prisma/engines prisma \ && mkdir -p public && pnpm prisma generate && pnpm next build # --- Laufzeit: Anwendung ------------------------------------------------------ FROM node:22.23.2-alpine3.24 AS runner WORKDIR /app ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ PORT=3000 \ HOSTNAME=0.0.0.0 \ MEDIA_DIR=/app/media RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 --ingroup nodejs nextjs COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static COPY --from=builder --chown=nextjs:nodejs /app/public ./public # Schreibbar fuer den Bild-Cache; im Cluster ein emptyDir (reiner Cache). RUN mkdir -p /app/.next/cache /app/media && chown -R nextjs:nodejs /app/.next/cache /app/media USER 1001 EXPOSE 3000 CMD ["node", "server.js"] # --- Laufzeit: Werkzeuge (Migration, Worker, Admin-Anlage) -------------------- FROM base AS tools ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 --ingroup nodejs nextjs COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules COPY --from=builder --chown=nextjs:nodejs /app/src ./src COPY --from=builder --chown=nextjs:nodejs /app/scripts ./scripts COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma COPY --from=builder --chown=nextjs:nodejs /app/prisma.config.ts /app/package.json /app/tsconfig.json ./ ENV PATH="/app/node_modules/.bin:${PATH}" USER 1001 # Standard: Migrationen anwenden. Worker: ["tsx", "scripts/worker.ts"]. CMD ["prisma", "migrate", "deploy"]