Dreistufiges Dockerfile mit standalone-Ausgabe; im Laufzeitabbild liegen weder Quelltext noch Bauwerkzeuge, und es läuft unter einem eigenen Benutzer. Die Migrationen erledigt ein eigener Einmaldienst aus der Bau-Stufe. Der Versuch, nur die Prisma-CLI ins Laufzeitabbild zu kopieren, scheiterte an ihren transitiven Modulen; sie alle mitzunehmen hätte das Abbild aufgebläht. Der Dienst läuft vor der App und muss sauber durchlaufen. Zwei Stellen mussten faul werden, weil Next beim Bauen Seitendaten sammelt und dabei Module lädt, die es zur Bauzeit noch ohne Umgebungsvariablen gibt: - Der Prisma-Client entsteht erst beim ersten Zugriff, über einen Proxy. - Die Auth.js-Konfiguration wird als Funktion übergeben. Ebenso liest prisma.config.ts die URL über process.env statt über env(), das beim Bauen ohne Datenbank abbricht. Dazu backup.sh, update.sh mit Rückrollpfad und scripts/release.sh. Der Dump wurde nachweislich in eine Wegwerf-Datenbank zurückgespielt und stimmt zeilengenau mit dem Original überein. Alle Skripte sind shellcheck-sauber. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
53 lines
1.7 KiB
Docker
53 lines
1.7 KiB
Docker
# syntax=docker/dockerfile:1
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Planer – Abbild für den Betrieb.
|
||
#
|
||
# Die Stufe "bauen" dient zugleich als Abbild für den Migrationsdienst: die
|
||
# Prisma-CLI bringt eine ganze Reihe Module mit, die im schlanken
|
||
# Laufzeitabbild nichts zu suchen haben. Siehe docker-compose.yml.
|
||
# ---------------------------------------------------------------------------
|
||
|
||
FROM node:24-alpine AS abhaengigkeiten
|
||
WORKDIR /app
|
||
RUN apk add --no-cache libc6-compat
|
||
COPY package.json package-lock.json ./
|
||
# Die Bauwerkzeuge werden gebraucht und bleiben in dieser Stufe.
|
||
RUN npm ci --ignore-scripts && npm rebuild prisma @prisma/engines esbuild unrs-resolver
|
||
|
||
|
||
FROM node:24-alpine AS bauen
|
||
WORKDIR /app
|
||
ENV NEXT_TELEMETRY_DISABLED=1
|
||
COPY --from=abhaengigkeiten /app/node_modules ./node_modules
|
||
COPY . .
|
||
# Der Prisma-Client wird erzeugt, bevor Next baut.
|
||
RUN npx prisma generate && npm run build
|
||
|
||
|
||
FROM node:24-alpine AS betrieb
|
||
WORKDIR /app
|
||
|
||
ENV NODE_ENV=production \
|
||
NEXT_TELEMETRY_DISABLED=1 \
|
||
PORT=3000 \
|
||
HOSTNAME=0.0.0.0 \
|
||
TZ=Europe/Berlin
|
||
|
||
RUN apk add --no-cache tzdata curl \
|
||
&& addgroup --system --gid 1001 planer \
|
||
&& adduser --system --uid 1001 --ingroup planer planer
|
||
|
||
# Die standalone-Ausgabe bringt nur die wirklich benutzten Module mit.
|
||
COPY --from=bauen --chown=planer:planer /app/.next/standalone ./
|
||
COPY --from=bauen --chown=planer:planer /app/.next/static ./.next/static
|
||
COPY --from=bauen --chown=planer:planer /app/public ./public
|
||
|
||
USER planer
|
||
EXPOSE 3000
|
||
|
||
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=5 \
|
||
CMD curl -fsS http://127.0.0.1:3000/api/health || exit 1
|
||
|
||
CMD ["node", "server.js"]
|