# syntax=docker/dockerfile:1 # --------------------------------------------------------------------------- # Lern-Bar – mehrstufiges Abbild # # Debian-slim statt Alpine, weil better-sqlite3 und @node-rs/argon2 dort # fertige Binärdateien mitbringen und nichts übersetzt werden muss. # --------------------------------------------------------------------------- ARG NODE_VERSION=22-bookworm-slim # --- Abhängigkeiten ------------------------------------------------------- FROM node:${NODE_VERSION} AS abhaengigkeiten WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends python3 build-essential \ && rm -rf /var/lib/apt/lists/* COPY package.json package-lock.json ./ RUN npm ci --ignore-scripts=false --no-audit --no-fund # --- Übersetzen ----------------------------------------------------------- FROM node:${NODE_VERSION} AS bau WORKDIR /app ENV NEXT_TELEMETRY_DISABLED=1 COPY --from=abhaengigkeiten /app/node_modules ./node_modules COPY . . RUN npm run build # --- Laufzeit ------------------------------------------------------------- FROM node:${NODE_VERSION} AS laufzeit WORKDIR /app ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ TZ=Europe/Berlin \ PORT=3000 \ HOSTNAME=0.0.0.0 \ LERNBAR_DATEN=/daten \ LERNBAR_INHALTE=/app/content \ LERNBAR_MIGRATIONEN=/app/migrationen # tini fängt Signale ab, damit `docker stop` sauber beendet. RUN apt-get update && apt-get install -y --no-install-recommends tini ca-certificates \ && rm -rf /var/lib/apt/lists/* # Standalone-Ausgabe von Next.js bringt genau die nötigen node_modules mit. COPY --from=bau /app/.next/standalone ./ COPY --from=bau /app/.next/static ./.next/static COPY --from=bau /app/public ./public # Inhalte und Migrationen liegen als Dateien im Abbild. COPY --from=bau /app/content ./content COPY --from=bau /app/src/lib/db/migrationen ./migrationen # Werkzeuge für Sicherung und Wiederherstellung im Container. COPY --from=bau /app/scripts/im-container ./werkzeuge RUN chmod +x ./werkzeuge/*.sh RUN mkdir -p /daten && chown -R node:node /daten /app USER node VOLUME ["/daten"] EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||3000)+'/api/gesundheit').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["node", "server.js"]