# syntax=docker/dockerfile:1 # ---------- Basis ---------- FROM node:24-alpine AS basis WORKDIR /app # tini beendet Prozesse sauber, openssl wird fuer die Geheimnis-Erzeugung gebraucht. RUN apk add --no-cache tini openssl ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 RUN corepack enable pnpm # ---------- Abhaengigkeiten ---------- FROM basis AS abhaengigkeiten # pnpm-workspace.yaml muss mit, sonst blockiert pnpm 12 die erlaubten Build-Skripte. COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ COPY prisma ./prisma COPY prisma.config.ts ./ RUN pnpm install --frozen-lockfile # ---------- Bauen ---------- FROM abhaengigkeiten AS bauen ARG APP_VERSION=0.0.0 ARG GIT_SHA="" ENV NEXT_PUBLIC_APP_VERSION=$APP_VERSION ENV NEXT_PUBLIC_GIT_SHA=$GIT_SHA COPY . . RUN pnpm exec prisma generate && pnpm build # ---------- Laufzeit ---------- FROM basis AS laufzeit ENV NODE_ENV=production ENV PORT=3000 ENV HOSTNAME=0.0.0.0 # --------------------------------------------------------------------------- # Chromium fuer das PDF-Uebergabeprotokoll – optional, und das mit Absicht (#041). # # Gemessen am 2026-10-25, und die Zahl ist der Grund fuer den Schalter: # # ohne Chromium 370 MB # mit Chromium 1,52 GB # # Alpines `chromium` kostet allein 1,13 GB – mehr als das dreifache der # gesamten Anwendung. Die meisten Installationen brauchen es nicht: die # Druckansicht gibt dasselbe Blatt ueber den Browser des Anwenders aus. # # `font-noto` sind davon nur 20 MB (`ttf-dejavu` waeren 10 MB und deckten # weniger ab). Es muss mit: Chromium ohne jede Systemschrift stellt Zeichen als # leere Kaesten dar, sobald eines nicht in unseren eigenen Schriften steht – # und das PDF waere trotzdem ein gueltiges PDF. Ein Fehler, der nicht meldet, # sondern falsch liefert. # # docker build --build-arg MIT_PDF=1 -t laufzettel . # # Ohne das Argument sagt der Endpunkt, was fehlt, und die Oberflaeche zeigt den # Knopf gar nicht erst (docs/betrieb/pdf.md). # --------------------------------------------------------------------------- ARG MIT_PDF=0 RUN if [ "$MIT_PDF" = "1" ]; then \ apk add --no-cache chromium font-noto; \ fi RUN addgroup -g 1001 -S laufzettel && adduser -S laufzettel -u 1001 -G laufzettel COPY --from=bauen --chown=laufzettel:laufzettel /app/.next/standalone ./ COPY --from=bauen --chown=laufzettel:laufzettel /app/.next/static ./.next/static COPY --from=bauen --chown=laufzettel:laufzettel /app/public ./public USER laufzettel EXPOSE 3000 ENTRYPOINT ["/sbin/tini", "--"] CMD ["node", "server.js"]