[ ENGINEERING_GUIDE ][ CI_CD ][ GITHUB_ACTIONS ][ NEXTJS ][ DEVOPS ]

CI/CD für Next.js — GitHub Actions von Tests bis Produktion (2026)

28. Mai 20269 Min. Lesezeit
Autor: DevStudio.itWeb & KI Studio

Lint, Build über scripts/build.cjs, Prisma, Vercel-Preview und Rollback — vollständige Pipeline für Next.js 15 auf Node 22, ehrlicher Ausgangspunkt ohne Workflow im Repo.

READ_TIME: 9 MIN_COMPLEXITY: MED_
STAMP: VERIFIED_BY_DS_

Kurzfassung

Für ein Next.js-Projekt auf Node 22, Next 15.5.18 und Build via scripts/build.cjs empfehlen wir eine GitHub-Actions-Pipeline: jeder PR = Qualität (lint + build), Merge auf main = Deploy auf Vercel. In diesem Repository gibt es noch keinen Ordner .github/workflows — der Artikel beschreibt den Zielzustand, den Sie gleich anlegen sollten, statt auf manuelles „bei mir geht’s“ zu vertrauen. Secrets (VERCEL_TOKEN, DATABASE_URL, API-Keys) nur in GitHub Secrets.

Für wen ist das

  • Teams mit 1–5 Entwicklern auf Next.js + Vercel
  • Projekte mit Prisma (postinstall: prisma generate, Migrate im Build-Skript)
  • Firmen, die auditierbare Deploy-Historie und Preview-URL pro PR wollen
  • Monorepos oder mehrere Apps in einem Repo (Abschnitt paths:)

Keyword (SEO)

ci cd nextjs github actions, pipeline nextjs 2026, vercel deployment automatisieren, github actions build nextjs, branch protection main, vercel rollback

Ausgangspunkt: ehrlicher Repo-Status

In vielen Produktionsprojekten „existiert“ die Pipeline im Kopf des Teams, nicht im Repo. Hier:

  • package.json verlangt Node 22.x (engines.node),
  • Next.js 15.5.18, Skripte: buildnode scripts/build.cjs, linteslint, postinstallprisma generate,
  • Keine Dateien .github/workflows/*.yml — CI muss bewusst ergänzt werden.

Das ist kein Mangel — normaler Reifegrad. Problematisch wird es, wenn Deploy vom Laptop dieselben Schritte wie der PR umgeht. Ziel: ein Artefakt — Commit bestand lint und build in Actions → derselbe Commit landet auf Vercel.

Was scripts/build.cjs macht (und warum CI es braucht)

Rohes next build in CI reicht oft nicht, wenn:

  1. Prisma — Skript lädt .env / .env.local (in Actions nicht im Repo), führt prisma generate aus und bei DATABASE_URL auch prisma migrate deploy, am Ende next build.
  2. Lokal hat der Entwickler eine DB; in CI kann der Build ohne Migration durchlaufen, wenn kein Secret gesetzt ist — aber generate ist nach npm ci nötig (auch via postinstall).

Pipeline-Folgerung: Build-Job muss npm run build (nicht rohes next build) mit passenden Env-Variablen in GitHub Secrets / Environments aufrufen. Für PR ohne DB reicht oft DATABASE_URL auf Shadow-DB oder Migration weglassen — je nach Team-Policy; Prod braucht volle Secrets im Environment production.

DATABASE_URL-Strategien in CI (Prisma)

Strategie Wann Plus / Minus
Gleiche URL wie Staging Kleines Team, eine Test-DB Schnell; Migrations-Kollision bei parallelen PRs
Eigene DB pro PR (Neon, Supabase Branch) Größeres Team Isolation; mehr Kosten / Setup
Kein DATABASE_URL im PR Nur statisches Frontend Build kann migrate deploy überspringen (Log in build.cjs); Schema muss im Repo aktuell sein
Volle URL nur auf main Kompromiss PR: lint + tsc + build ohne Migrate; Prod: volle Pipeline

Im DevStudio-Style-Build ohne DATABASE_URL schreibt das Skript eine Meldung und überspringt prisma migrate deploy, führt aber prisma generate aus — konsistent mit postinstall, verhindert „Client not generated“.

Empfohlene Aufteilung: PR vs. main

Schritt Pull Request Push auf main
npm ci ja ja
npm run lint (ESLint) ja ja
npx tsc --noEmit ja (bei TypeScript) ja
npm run build ja ja
Unit-Tests ja, wenn vorhanden ja
Vercel-Deploy Preview ja (Git-Integration oder Actions)
Vercel-Deploy Production ja
Lighthouse CI optional optional (z. B. Cron)

Regel: nichts in main mergen, was nicht denselben build wie Produktion bestanden hat.

Vollständiges Workflow-Beispiel (.github/workflows/ci.yml)

Die folgende Datei ist kopierfertig anpassbar. Nutzt Node 22, npm-Cache, lint, typecheck und build wie in diesem Repo.

name: CI

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  quality:
    runs-on: ubuntu-latest
    timeout-minutes: 25
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js 22
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: ESLint
        run: npm run lint

      - name: TypeScript (no emit)
        run: npx tsc --noEmit

      - name: Build (Prisma + Next via scripts/build.cjs)
        run: npm run build
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          NEXT_PUBLIC_SITE_URL: ${{ vars.NEXT_PUBLIC_SITE_URL || 'https://example.com' }}

  deploy-preview:
    if: github.event_name == 'pull_request'
    needs: quality
    runs-on: ubuntu-latest
    environment: preview
    steps:
      - uses: actions/checkout@v4
      - uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          scope: ${{ secrets.VERCEL_ORG_ID }}

  deploy-production:
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    needs: quality
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'
          github-token: ${{ secrets.GITHUB_TOKEN }}
          scope: ${{ secrets.VERCEL_ORG_ID }}

Einfachere Alternative: Vercel Git Integration aktivieren — Vercel baut Preview pro PR, Job quality in Actions bleibt Merge-Gate. Viele Teams kombinieren: Actions = lint/tsc/build, Vercel = Hosting + URL.

Secrets und Variablen — wo was liegt

Name Wo Hinweise
VERCEL_TOKEN GitHub Secret Token aus Vercel Account Settings
VERCEL_ORG_ID, VERCEL_PROJECT_ID GitHub Secret Aus .vercel/project.json nach vercel link
DATABASE_URL Secret + Vercel Env Gleicher Wert wie Prod für migrate deploy
OPENAI_API_KEY, Stripe usw. Secret / Vercel Nie im Repo oder in Actions-Logs
NEXT_PUBLIC_* Variables (nicht geheim) oder Vercel Identisch in PR-Build und Prod, sonst kehrt „bei mir geht’s“ zurück

Im Repo: Settings → Secrets and variables → Actions. Für Produktion Environment production mit optional Required reviewers (1–2 Personen).

Branch Protection auf main

Minimum ab Tag eins:

  • Require pull request before merging
  • Require status check quality (Job-Name aus Workflow)
  • Require branch to be up to date
  • Do not allow bypassing (auch Admin, wenn das Team diszipliniert ist)
  • Optional: require signed commits

So landet kein Build in Prod, der npm run lint und npm run build auf Node 22 nicht bestanden hat.

Preview-URL pro PR

Vercel Git Integration (empfohlen zum Start):

  • automatische URL wie projekt-git-branch-xyz.vercel.app,
  • Bot-Kommentar im PR mit Link,
  • QA und Kunde prüfen vor Merge.

GitHub Actions + vercel-action (wie im YAML oben):

  • volle Kontrolle, derselbe Token wie Prod-Deploy,
  • sinnvoll bei einem Pipeline-YAML statt Vercel-Panel.

In beiden Fällen: NEXT_PUBLIC_* auf Preview nicht leer — sonst grüner PR-Build, aber anderes UI auf Preview als Prod.

Env-Sync: in Vercel Variablen von Production nach Preview kopieren (oder Vercel CLI vercel env pull). In GitHub dieselben NEXT_PUBLIC_* als Variables — dann baut Job quality denselben Code wie Preview. Secrets (DATABASE_URL, STRIPE_SECRET_KEY) nur in Secrets.

Monorepo: nicht alles bei jedem PR bauen

Bei apps/web und packages/ui im selben Repo separate Workflows mit Pfadfilter:

on:
  pull_request:
    paths:
      - 'apps/web/**'
      - 'packages/ui/**'
      - 'package-lock.json'

Oder paths-ignore für Doku (docs/**, content/blog/**), um keinen 8-Minuten-Build bei Blog-Tippfehler zu starten — sofern der Blog nicht Teil desselben Next.js-Pakets ist (bei monolithischer Marketing-Site oft trotzdem Full-Build).

Rollback auf Vercel in ~60 Sekunden

Prod-Deploy auf Vercel ist ein neues Deployment; alte Builds bleiben.

Notfallprozedur:

  1. Vercel Dashboard → Deployments
  2. Letztes funktionierendes Deployment finden (vorheriger Commit)
  3. ⋯ → Promote to Production

Oft unter einer Minute. Pipeline ersetzt Rollback nicht — sie stellt sicher, dass der promotierte Build einmal grün im PR war. Deploy vom Laptop „schnell“ neben CI vermeiden — sonst kann Rollback im Panel eine andere Version wiederherstellen als erwartet.

Bei eigenem Server (Docker): Image-Tag = Commit-SHA; Rollback = vorheriger Tag im Orchestrator. Gleiche Regel: ein Artefakt aus CI.

Sicherheit in CI/CD

  • permissions: contents: read standardmäßig — minimale GITHUB_TOKEN-Rechte
  • separates Environment production mit Approval
  • Dependabot / npm audit in wöchentlichem Workflow
  • Secrets und volle .env nie in Logs echoen — Actions maskiert secrets.*, eigene Skripte müssen sauber sein
  • Rotation von VERCEL_TOKEN und API-Keys quartalsweise oder nach Team-Austritt

Häufige Fehler (und Vermeidung)

Fehler Folge Fix
PR-Build ohne NEXT_PUBLIC_* Anderes Bundle als Prod Variables in GitHub + Vercel Preview
next build statt npm run build Kein Prisma migrate/generate Immer Repo-Skript
Node 20 in Actions, 22 in engines Zufällige native Modul-Fehler node-version: '22'
Kein npm-Cache 8 Min statt 3 cache: 'npm' in setup-node
Deploy vom Laptop + CI Zwei Wahrheiten Nur Merge → main → Deploy
Keine Branch Protection Prod-Bruch am Freitagabend Pflicht-Check quality

FAQ

Ersetzen GitHub Actions Vercel?

Nein. Actions = Qualitätskontrolle und optional CLI-Deploy; Vercel = Hosting, CDN, Preview, Rollback. Meist: Actions für lint/build, Vercel für App-Ausführung.

prisma migrate deploy in CI?

In diesem Projekt macht das scripts/build.cjs, wenn DATABASE_URL gesetzt ist. Im PR Test-DB oder Migration weglassen — Schema muss trotzdem passen (generate nötig). Auf main/prod muss DATABASE_URL vollständig sein.

Was ohne Tests?

Mit lint + tsc + build starten. Tests hinzufügen bei kritischen Pfaden (Zahlung, Vertrags-API). Pipeline liefert schon ~80 % Wert.

Monorepo mit drei Apps?

Drei Workflows mit paths: oder ein Workflow mit strategy.matrix — kein globaler Build ohne Filter.

Node-Version mit Vercel synchronisieren?

In Vercel Project Settings Node.js 22.x, passend zu engines in package.json.

Troubleshooting: roter Build in Actions

  • prisma generate failed — Node (22), ob npm ci fertig, Schema im Repo korrekt.
  • migrate deploy failed — DB von GitHub aus unreachable (Firewall), falsche Migration, Konflikt mit manuellen DB-Änderungen.
  • next build OOM — Runner upgraden (selten) oder schwere Imports prüfen.
  • Lint fail im PR — lokal npm run lint auf Node 22; nicht mit --no-verify mergen.
  • Preview OK, Prod nicht — Vercel Production vs. Preview Environment Variables vergleichen; oft fehlt ein NEXT_PUBLIC_*.

Actions-Logs sind der Audit vor Produktion — genau einen Schritt lesen, der rot ist.

Cache und parallele PRs

Mit concurrency: cancel-in-progress: true bricht ein neuer Push auf demselben Branch den laufenden CI-Lauf ab — spart Minuten bei schnellen Fix-Commits. Ergänzen Sie npm- und .next/cache-Caching in Actions, wenn Builds regelmäßig über sechs Minuten dauern. Bei Prisma-Projekten: prisma generate läuft ohnehin über postinstall — teure Schritte sind meist next build und Typecheck; dort lohnt sich stabile Node-22-Version und identische Lockfile-Disziplin (npm ci, nie npm install in CI).

Plan — Implementierung an einem Tag

  1. .github/workflows/ci.yml hinzufügen (Fragment oben).
  2. Secrets + Variables (DATABASE_URL, Vercel, NEXT_PUBLIC_*).
  3. Branch Protection auf main.
  4. Repo mit Vercel verbinden (falls noch nicht).
  5. Test-PR — grüner quality + Preview-URL.
  6. Mergen — Production-Deployment prüfen, Rollback-Prozedur ins Team-README.

Zusammenfassung

CI/CD für Next.js 15 auf Node 22 ist kein Hexenwerk — wiederholbar: npm ci → lint → typecheck → npm run build (Prisma + Next) pro PR, Deploy auf Vercel nach Merge, Secrets außerhalb des Repos, Preview zur Abnahme, Rollback via Promote im Panel. Fehlende Workflows im Repository sind das Signal, das jetzt zu ergänzen — bevor manueller Deploy mehr kostet als ein Tag Produktions-Reparatur.

Pipeline für Ihr Projekt?

  • Kontakt aufnehmenpackage.json, Vercel und Prisma für Ihren Fall prüfen
  • Web-Apps — Next.js, Hosting und DevOps aus einer Hand

Über den Autor

Wir bauen schnelle Websites, Web/Mobile-Apps, KI-Chatbots und Hosting — mit Fokus auf SEO und Conversion.

Empfohlene Links

Von Theorie zu Produktion — Branchly, Hosting-Stack, Betreuung und Referenzen.

GEFÄLLT EUCH UNSERE ARCHITEKTUR DES DENKENS? LASST UNS GEMEINSAM BAUEN.

[ PROJEKT_KONFIGURATION_STARTEN ]