All checks were successful
Container-Image bauen und veröffentlichen / build-and-push (push) Successful in 2m22s
Der Workflow bricht weiter mit ENOSPC ab, jetzt in beiden npm-Stufen gleichzeitig nach 8,2 Sekunden - der Datentraeger ist praktisch voll. - prisma-cli baut auf deps statt auf base auf. Damit laufen die beiden npm-Installationen nacheinander statt parallel, was den gleichzeitigen Platzbedarf halbiert. Die deps-Schicht liegt ohnehin vor. - Der Workflow protokolliert vor dem Bauen Belegung, Inodes und docker system df. ENOSPC heisst auch "keine Inodes frei", was df -h nicht zeigt - beim naechsten Fehlschlag stehen die Zahlen im Log. - Ungenutzter Build-Cache aelter als 24h wird vor dem Bauen freigegeben. Jeder abgebrochene Versuch hinterlaesst sonst Schichten und macht es beim naechsten Mal enger. Betrifft nur Cache, keine Images, Volumes oder Container. Geprueft: Image baut mit serialisierten Stufen, Container startet, Migrationen laufen, Healthcheck gruen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
103 lines
4.4 KiB
Docker
103 lines
4.4 KiB
Docker
# syntax=docker/dockerfile:1
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Basis – Debian slim statt Alpine, weil Prisma dort ohne musl-Sonderengine
|
||
# auskommt. openssl wird von der Prisma Query Engine benötigt.
|
||
# ---------------------------------------------------------------------------
|
||
FROM node:22-bookworm-slim AS base
|
||
ENV NEXT_TELEMETRY_DISABLED=1
|
||
RUN apt-get update \
|
||
&& apt-get install -y --no-install-recommends openssl ca-certificates \
|
||
&& rm -rf /var/lib/apt/lists/*
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Abhängigkeiten
|
||
# ---------------------------------------------------------------------------
|
||
FROM base AS deps
|
||
WORKDIR /app
|
||
COPY package.json package-lock.json ./
|
||
# Cache in derselben Schicht entfernen: Er wird nur zur Installation gebraucht
|
||
# und bliebe sonst dauerhaft im Image-Layer liegen.
|
||
RUN npm ci --no-audit --no-fund && npm cache clean --force
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Prisma-CLI – isolierte Installation samt transitiver Abhängigkeiten, damit
|
||
# `migrate deploy` beim Start läuft. Das Standalone-Bundle enthält nur, was die
|
||
# Anwendung selbst importiert, und damit nicht den CLI.
|
||
#
|
||
# Bewusst FROM deps statt FROM base: Damit wartet diese Stufe auf die
|
||
# Abhängigkeiten, statt parallel zu ihnen zu installieren. Das halbiert den
|
||
# gleichzeitigen Platzbedarf auf dem Build-Host. Die Schicht von deps liegt
|
||
# ohnehin schon vor, kostet hier also nichts zusätzlich.
|
||
# ---------------------------------------------------------------------------
|
||
FROM deps AS prisma-cli
|
||
WORKDIR /prisma-cli
|
||
RUN npm init -y > /dev/null \
|
||
&& npm install --omit=dev --no-audit --no-fund prisma@6.16.0 \
|
||
&& npm cache clean --force
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Build
|
||
# ---------------------------------------------------------------------------
|
||
FROM base AS builder
|
||
WORKDIR /app
|
||
COPY --from=deps /app/node_modules ./node_modules
|
||
COPY . .
|
||
|
||
# Platzhalter nur für den Build: Die Auth-Konfiguration wird beim Prerendern
|
||
# ausgewertet und würde ohne gesetzte Variable werfen. ARG statt ENV, damit
|
||
# nichts davon im fertigen Image landet – der echte Wert kommt zur Laufzeit.
|
||
ARG NEXTAUTH_SECRET=build-time-placeholder
|
||
ARG DATABASE_URL=file:/tmp/build.db
|
||
|
||
RUN npx prisma generate
|
||
RUN npm run build
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Laufzeit
|
||
# ---------------------------------------------------------------------------
|
||
FROM base AS runner
|
||
WORKDIR /app
|
||
|
||
ENV NODE_ENV=production \
|
||
PORT=3000 \
|
||
HOSTNAME=0.0.0.0 \
|
||
DATABASE_URL=file:/app/data/syncova.db
|
||
|
||
RUN groupadd --system --gid 1001 nodejs \
|
||
&& useradd --system --uid 1001 --gid nodejs nextjs
|
||
|
||
# Standalone-Server samt der von Next.js ermittelten Abhängigkeiten
|
||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||
|
||
# Prisma: Schema, Migrationen und generierter Client für die Anwendung
|
||
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
|
||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma
|
||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma/client ./node_modules/@prisma/client
|
||
|
||
# Prisma-CLI in eigenem Verzeichnis, damit er das Standalone-Bundle nicht stört
|
||
COPY --from=prisma-cli --chown=nextjs:nodejs /prisma-cli/node_modules ./prisma-cli/node_modules
|
||
|
||
# Skripte für die Erstanlage des Admin-Zugangs (docker exec)
|
||
COPY --from=builder --chown=nextjs:nodejs /app/scripts ./scripts
|
||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/bcryptjs ./node_modules/bcryptjs
|
||
|
||
COPY --chown=nextjs:nodejs docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||
# Windows-Zeilenenden würden den Shebang unbrauchbar machen
|
||
RUN sed -i 's/\r$//' /usr/local/bin/docker-entrypoint.sh \
|
||
&& chmod +x /usr/local/bin/docker-entrypoint.sh
|
||
|
||
# Ablage der SQLite-Datenbank – als Volume einhängen, sonst ist sie flüchtig
|
||
RUN mkdir -p /app/data && chown -R nextjs:nodejs /app/data
|
||
VOLUME ["/app/data"]
|
||
|
||
USER nextjs
|
||
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)+'/auth/signin').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
|
||
|
||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||
CMD ["node", "server.js"]
|