Docker-Image produktionsreif machen
All checks were successful
Container-Image bauen und veröffentlichen / build-and-push (push) Successful in 2m40s

- trustHost für Auth.js: selbst gehostet wird der Host sonst mit
  UntrustedHost abgelehnt und die Anmeldung schlägt fehl
- Prisma-CLI in eigener Stage installieren; im Standalone-Bundle fehlen
  seine transitiven Abhängigkeiten, `migrate deploy` brach beim Start ab
- Zeilenenden des Entrypoints im Image normalisieren

Getestet: Container startet, wendet Migrationen an, Anmeldung und
Admin-Bereich antworten mit 200.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Weapie 2026-09-07 16:32:45 +02:00
parent 328f042307
commit 1f9543efd8
3 changed files with 25 additions and 10 deletions

View File

@ -18,6 +18,15 @@ WORKDIR /app
COPY package.json package-lock.json ./ COPY package.json package-lock.json ./
RUN npm ci RUN npm ci
# ---------------------------------------------------------------------------
# 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.
# ---------------------------------------------------------------------------
FROM base AS prisma-cli
WORKDIR /prisma-cli
RUN npm init -y > /dev/null && npm install --omit=dev prisma@6.16.0
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Build # Build
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -26,11 +35,11 @@ WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/node_modules ./node_modules
COPY . . COPY . .
# Der Build liest NEXTAUTH_SECRET nicht aus, braucht die Variable aber, damit # Platzhalter nur für den Build: Die Auth-Konfiguration wird beim Prerendern
# die Auth-Konfiguration beim Prerendern nicht wirft. Der echte Wert kommt zur # ausgewertet und würde ohne gesetzte Variable werfen. ARG statt ENV, damit
# Laufzeit aus der Umgebung. # nichts davon im fertigen Image landet – der echte Wert kommt zur Laufzeit.
ENV NEXTAUTH_SECRET=build-time-placeholder ARG NEXTAUTH_SECRET=build-time-placeholder
ENV DATABASE_URL=file:/tmp/build.db ARG DATABASE_URL=file:/tmp/build.db
RUN npx prisma generate RUN npx prisma generate
RUN npm run build RUN npm run build
@ -53,18 +62,21 @@ RUN groupadd --system --gid 1001 nodejs \
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ 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/.next/static ./.next/static
# Prisma: Schema, Migrationen, generierter Client und CLI für `migrate deploy` # 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/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 ./node_modules/.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
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
# 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) # 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/scripts ./scripts
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/bcryptjs ./node_modules/bcryptjs 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 COPY --chown=nextjs:nodejs docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh # Windows-Zeilenenden würden den Shebang unbrauchbar machen
RUN sed -i 's/ $//' /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 # Ablage der SQLite-Datenbank – als Volume einhängen, sonst ist sie flüchtig
RUN mkdir -p /app/data && chown -R nextjs:nodejs /app/data RUN mkdir -p /app/data && chown -R nextjs:nodejs /app/data

View File

@ -8,7 +8,7 @@ if [ -z "$NEXTAUTH_SECRET" ]; then
fi fi
echo "Wende ausstehende Datenbank-Migrationen an (${DATABASE_URL})…" echo "Wende ausstehende Datenbank-Migrationen an (${DATABASE_URL})…"
node ./node_modules/prisma/build/index.js migrate deploy node ./prisma-cli/node_modules/prisma/build/index.js migrate deploy --schema ./prisma/schema.prisma
echo "Starte Syncova Policies…" echo "Starte Syncova Policies…"
exec "$@" exec "$@"

View File

@ -69,6 +69,9 @@ export const authConfig: NextAuthConfig = {
pages: { pages: {
signIn: "/auth/signin", signIn: "/auth/signin",
}, },
// Selbst gehostet: Auth.js vertraut sonst nur Vercel-Hosts und lehnt
// Anfragen hinter Reverse-Proxy/Container mit UntrustedHost ab.
trustHost: true,
// Kein Fallback-Secret: fehlt NEXTAUTH_SECRET, soll der Start fehlschlagen, // Kein Fallback-Secret: fehlt NEXTAUTH_SECRET, soll der Start fehlschlagen,
// statt still mit einem öffentlich bekannten Wert zu signieren. // statt still mit einem öffentlich bekannten Wert zu signieren.
secret: process.env.NEXTAUTH_SECRET! secret: process.env.NEXTAUTH_SECRET!