Skip to content
dopq HQ
Go back

Aber lokal lief es doch! Warum dein Astro-Projekt auf Cloudflare Pages crasht (und wie GitHub Actions hilft)

Edit page

Es ist der absolute Klassiker im Entwickleralltag: Man codet hochkonzentriert ein neues Feature oder schreibt einen frischen Blogpost, testet alles lokal im Browser, drückt glücklich auf git push – und wenige Minuten später leuchtet das Dashboard von Cloudflare Pages dunkelrot. Der Build ist fehlgeschlagen.

Besonders in Astro-Projekten stolpert man regelmäßig über das Phänomen, dass der lokale Dev-Server (npm run dev) keinen Mucks von sich gibt, während der Produktions-Build (npm run build) krachend gegen die Wand fährt.

Warum ist das so? Und wie bauen wir uns einen digitalen Türsteher, der das in Zukunft verhindert?

Das Problem: Der “faule” Dev-Server

Der Hauptgrund für dieses Diskrepanz liegt in der fundamental unterschiedlichen Arbeitsweise von Astros Entwicklungs- und Build-Umgebung.

Wenn du lokal npm run dev startest, verhält sich Astro extrem ressourcenschonend und “faul” (Lazy Loading). Es generiert Seiten, Routen und Endpunkte erst in dem Moment, in dem du sie explizit im Browser aufrufst.

Hast du beispielsweise eine dynamische Route für deinen RSS-Feed (/rss.xml) oder deine Sitemap, wird dieser Code lokal beim Entwickeln niemals ausgeführt, es sei denn, du tippst die URL aktiv in die Adresszeile.

Cloudflare Pages hingegen macht beim Deployment keine halben Sachen. Es führt den echten Produktions-Build aus. Dabei wird jede einzelne Seite, jede Route und jeder Endpunkt von Anfang bis Ende durchgerendert. Liegt irgendwo im Projekt ein versteckter i18n-Konfigurationsfehler, ein fehlerhafter Import oder ein Typ-Konflikt in einer Content-Collection, fliegt dir der gesamte Prozess um die Ohren.

Die Lösung für lokale Tests

Um böse Überraschungen im Deployment-Log zu minimieren, sollte man sich angewöhnen, vor dem Push eine produktionsnahe Simulation auf dem eigenen Rechner laufen zu lassen:

# Erzeugt den echten Produktions-Build lokal
pnpm build

Erst hier zieht Astro die Samthandschuhe aus. Wenn der Build lokal ohne Fehler durchläuft, stehen die Chancen extrem gut, dass auch Cloudflare grünes Licht gibt.

Die ultimative Absicherung: GitHub Actions als Gatekeeper

Da wir Menschen aber vergesslich sind und das manuelle Bauen vor jedem Push wertvolle Zeit kostet, überlassen wir diesen Job lieber einer Automatisierung. Mit GitHub Actions bauen wir uns eine CI-Pipeline (Continuous Integration), die bei jedem Push und jedem Pull Request unbestechlich prüft, ob das Projekt wirklich reif für die Produktion ist.

Erstelle dazu eine Datei unter .github/workflows/ci.yml in deinem Projekt:

name: CI (Branch Sanity Check)

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

jobs:
  verify:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10

      - name: Get pnpm store directory
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

      - name: Setup pnpm cache
        uses: actions/cache@v4
        with:
          path: ${{ env.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: Install Dependencies
        run: pnpm install --frozen-lockfile

      - name: Run Quality Gate (Typecheck & Build)
        run: |
          pnpm exec astro check
          pnpm build

Warum genau dieses Setup?

  1. Effizientes Caching: Durch das Sichern des pnpm-Stores via actions/cache dauert die Installation der Node-Module bei Folge-Builds oft nur wenige Sekunden.
  2. --frozen-lockfile: Sorgt dafür, dass exakt die Abhängigkeiten installiert werden, die in deiner lokalen pnpm-lock.yaml stehen. Keine stillschweigenden Versions-Updates in der Cloud.
  3. Zweistufiger Check: astro check validiert zuerst TypeScript- und Komponentenstrukturen auf logische Fehler. Erst wenn da alles passt, startet pnpm build den finalen Härtetest für alle Routen.

Fazit

Der Satz “Auf meinem Rechner lief es aber!” verliert dank moderner CI-Pipelines seinen Schrecken. Indem wir den Produktions-Build als zwingende Bedingung vor jedes Deployment schalten, halten wir unsere Codebasis sauber und sparen wertvolle Build-Minuten auf unserer Hosting-Plattform.

Lass die Maschine die Fehler suchen, bevor es deine Produktionsumgebung tun muss!


Edit page
Share this post:

Previous Post
Dem KI-Overengineering entkommen: Warum LLMs zu viel Code schreiben und wie wir sie zähmen
Next Post
Coding Principle: Occam's Razor (Ockhams Rasiermesser)