Zum Hauptinhalt springen
EinfachAleks
About
About RSS-Feed

Von IONOS Zu Cloudflare Pages — Ein Migrations-Bericht

2026-05-12
diy
8.1k Wörter
7 min Lesezeit
von  EinfachAleks

Seit dem 11. Mai 2026 läuft einfach-aleks.com nicht mehr über IONOS, sondern über Cloudflare Pages. Der alte Pfad — hexo generate lokal bauen, hexo deploy schiebt die Files per SFTP auf einen IONOS-Hoster, davor ein Cloudflare-Proxy als CDN — ist Geschichte. Der neue Pfad ist git push origin main und der Rest passiert von alleine.

Klingt unspektakulär, war aber überfällig. Es gab einen Grund der mich überzeugt hat das Wochenende dafür zu opfern, und einen Bonus-Grund den ich im Nachhinein zugeben muss.

Warum überhaupt etwas ändern

Der Grund: ein abgekündigter SSH-Stack im Deploy-Pfad

Hexo hat ein offizielles SFTP-Deployer-Plugin (hexo-deployer-sftp) und ich hab es seit der WordPress-zu-Hexo-Migration 2021 benutzt. Das Dependabot-Alert hat mich nicht erst 2026 darauf hingewiesen — ich hab es jahrelang einfach weggeklickt. Typisches Entwicklerproblem: “mache ich irgendwann mal später”. Im Mai 2026 hab ich dann endlich genauer hingeschaut. Das Plugin hat seit Februar 2020 keinen Release mehr gesehen. Es bringt ein veraltetes [email protected] mit, das eine OS-Command-Injection-Lücke hat (CVE-2020-26301). Patch existiert ab [email protected], aber der Upgrade-Pfad ist tot — die Bibliothek dazwischen (sftp-sync-deploy) ist seit Dezember 2018 unmaintained.

Das heißt: zwei tote Pakete, ein offener High-Severity-CVE, kein realistischer Fix-Weg. Entweder selber forken und upgraden — was bei einem Hobby-Blog kein vernünftiger Aufwand ist — oder den ganzen SFTP-Pfad rauswerfen.

Bonus-Grund: Atomic Deploys

Bei SFTP überträgt man Files einzeln. Während der Upload läuft, ist die Seite in einem Mischzustand: neue HTML-Files referenzieren CSS-Files die noch nicht da sind, ein Mobil-User bekommt 404 auf ein Bild das gerade hochgeladen wird. Realistisch ein Risiko-Fenster von 10–20 Sekunden pro Deploy. Bei einem Hobby-Blog mit ein paar Hundert Lesern pro Tag fällt das niemandem auf, aber elegant ist es nicht.

Atomic Deploys heißt: Cloudflare lädt den kompletten Build hoch, validiert ihn, und schaltet erst dann den Edge-Router auf die neue Version um. Null Übergangszustand, keine halbfertigen Seiten.

Was ich mir angeschaut habe

Bevor ich Cloudflare Pages genommen hab, war kurz die Frage: gibt’s einen besseren Kandidaten?

Die üblichen Alternativen sind Netlify, Vercel oder selbst hosten auf einem VPS. Meine Anforderungen waren:

  • Free-Tier muss für einen Blog mit deutlich unter 100k Page-Views/Monat reichen
  • Custom Domain mit Apex (einfach-aleks.com, nicht nur www.) ohne Workarounds
  • HTTPS automatisch
  • Atomic Deploys
  • Build im eigenen CI, nicht im Anbieter-CI (ich will pnpm-Caching, kontrollierte Node-Version, eigene Tests vor Deploy)

Netlify und Vercel sind beide solide, aber DNS und CDN wären weiter bei Cloudflare und Pages/Workers ist mein anderer Stack ohnehin — den Anbieter zu konzentrieren wo möglich ist mir lieber.

Was Cloudflare Pages für mich entschieden hat:

  1. Die DNS-Zone ist eh schon in meinem Cloudflare-Account. CNAME-Flattening am Apex erspart den ganzen “wie zeige ich einfach-aleks.com ohne A-Record auf irgendwas”-Tanz.
  2. Free-Tier liegt bei 500 Builds/Monat, 20.000 Files pro Projekt, unlimited Bandwidth. Mein Blog: 443 Files, deutlich unter 100 Deploys/Monat. Faktor 5–40 Headroom.
  3. Auto-Cache-Purge bei jedem Deploy. Das räumt alte Versionen am Edge in einem Rutsch weg, ohne dass ich im Dashboard händisch nachhelfen muss.

Der Schnitt

Die eigentliche Cutover-Sequenz, kurz:

  1. Cloudflare-API-Token erzeugen mit Account → Pages → Edit und Account-Settings → Read. Kein Global-API-Key, ein scoped Token. Den habe ich als GitHub-Secret CLOUDFLARE_API_TOKEN ins production-Environment gelegt, dazu noch die Account-ID.
  2. Pages-Projekt anlegen als Direct-Upload-Projekt (NICHT “Connect to Git” — ich will dass mein eigenes CI baut, nicht das Cloudflare-CI). Production-Branch main.
  3. Workflow umbauen. Der GitHub-Actions-Workflow läuft jetzt so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
permissions:
contents: read
deployments: write
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v6
with: { node-version-file: .nvmrc, cache: pnpm }
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm run test
- run: pnpm run build
- run: pnpm run lint:links
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy public/ --project-name=einfach-aleks --branch=${{ github.ref_name }}
- if: github.ref == 'refs/heads/main'
run: pnpm exec hexo ping

Vorher gab es eine pnpm run deploy-Stufe die SFTP-Credentials aus einer .env injiziert hat. Die ist komplett raus. hexo-deployer-sftp aus den Dependencies geflogen, pnpm-lock.yaml schrumpft um die ganze ssh2-Familie.

  1. DNS-Cutover. Im Cloudflare-Dashboard “Custom Domain” am Pages-Projekt: einfach-aleks.com und www.einfach-aleks.com dazu. Cloudflare hat die alten A/AAAA-Records auf den IONOS-Origin selber entfernt und CNAME-Flattening am Apex eingerichtet. SSL-Zertifikat (Google Trust Services, gültig bis August 2026) wurde innerhalb von etwa fünf Minuten provisioniert.

  2. Smoke und Soak. pnpm run smoke einmal grün, dann acht Stunden zugucken ob irgendwas Komisches passiert. Tat es nicht. Am 12. Mai hab ich die alten HEXO_DEPLOY_SFTP_*-Secrets aus dem GitHub-Environment gelöscht und den Feature-Branch entfernt.

Was jetzt anders ist

Drei Sachen die im Alltag spürbar sind:

Edge-Cache läuft automatisch sauber. Jeder Deploy invalidiert die CDN-Edges global, gemessene Propagation unter 30 Sekunden. Auch der _headers-File im Repo, den ich später ergänzt habe, kann pro Pfad-Pattern eigene Cache-Times setzen — fingerprinted CSS/JS immutable, Feeds 5 Minuten, llms.txt 1 Stunde, indexnow.txt 60 Sekunden.

Pipeline-Gates sind ehrlich. Vor dem Deploy laufen jetzt zwingend:

  • pnpm run test — Frontmatter-Validierung (UUID, Datum, Kategorie) und Build-Smoke
  • pnpm run build — der eigentliche Hexo-Build
  • pnpm run lint:links — checkt alle Links die nach außen gehen

Wenn einer davon rot wird, kommt nichts auf Production. Vorher hab ich die Tests separat in einer ci.yml gehabt, aber der deploy.yml hat sie nicht ausgeführt — wenn ich einen Tippfehler gemacht hab und nichts gegen den main gepusht hab außer dem Post, ging der Deploy trotzdem durch. Jetzt nicht mehr.

Search-Engine-Ping fährt mit. Nach dem Pages-Deploy läuft ein hexo ping, das per IndexNow Bing/Yandex/Naver/Seznam/Yep über die neue/aktualisierte URL informiert, parallel via XML-RPC Pingomatic und Twingly anfunkt, und über WebSub den RSS-Hub pubsubhubbub.appspot.com benachrichtigt. Hatte ich vorher nicht — kein WordPress-Update-Services-Äquivalent. Das hab ich im Zuge der Migration mitgebaut, weil’s eh schon die Pipeline aufgemacht hat.

Der gesamte CI-Lauf (install + test + build + link-check + deploy + ping) liegt bei rund 90 Sekunden. Davon ist der reine Pages-Upload zwei bis drei Sekunden — public/ mit etwa 440 Files ist nichts für einen modernen CDN. Der Rest ist pnpm-install (gecacht), Hexo-Build und die Link-Validierung.

Performance-mäßig: nach der Migration und einer kleinen Lighthouse-Sanierungsrunde (CLS war auf Mobile-Slow-4G noch 1.09, jetzt 0.00) treffen alle sieben Hauptseitentypen 100/100/100/100 auf Mobile und Desktop. Hat mit der Migration selbst nichts zu tun — die alte IONOS-Variante war schon schnell — aber die saubere Pipeline hat die Iteration deutlich angenehmer gemacht.

Was es gekostet hat

Damit niemand glaubt das ist umsonst:

  • Cloudflare-Account und Pages-Projekt: Free. Kreditkarte nicht hinterlegt.
  • Cloudflare-API-Token: kostenlos, aber muss man einmal sauber scopen. Wer den Global-API-Key nimmt, hat in seinen GitHub-Secrets effektiv einen Account-Master-Key liegen — bitte nicht machen.
  • Zeitaufwand: ungefähr ein Tag verteilt über zwei Abende. Davon ein Großteil Recherche und Plan schreiben; die eigentliche Code-Änderung war eine Stunde, die DNS-Umstellung fünf Minuten.
  • Eine kleine Sünde: der Workflow hat einen ENV-Schalter FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true". Hintergrund: cloudflare/wrangler-action@v3 läuft intern auf Node.js 20, und GitHub deprecated Node 20 auf den Runnern ab Juni 2026 mit Komplettentfernung im September. Bis es einen wrangler-action@v4 mit nativem Node 24 gibt, ist der Force-Flag der Interim-Fix. Ist seit Mai 2026 als Open-Issue beim Action-Repo bekannt. Der Flag fliegt raus sobald v4 da ist.
  • Backup-Schmerz: der alte IONOS-Origin liegt noch ein paar Wochen brach. Mein letzter Hexo-Build von dort ist als Cold-Backup auf einer externen Platte. Wenn nach drei Monaten nichts auffällt, baue ich den Hoster ab.

Außerdem hab ich package.json von einem "deploy"-Skript befreit, das niemand mehr braucht. git push origin main ist die einzige Aktion mit Production-Effekt. Wer einen lokalen Preview will, läuft pnpm run build && pnpm dlx wrangler pages deploy public/ — geht, brauche ich aber nie.

Was ich beim nächsten Mal anders machen würde

Sachen versuchen sofort zu erledigen.


Der Blog ist seit einer Dekade mein Werkzeug für genau diese Art von Aufräum-Übungen. Das hier war eine davon.

AIO in Der Praxis — Artificial Intelligence Optimization Schritt Für Schritt

Profilbild von EinfachAleks

EinfachAleks

Web-Development / Technik / Games

Kategorien

gaming
7
news
13
software
17
diy
13
security
10
support
4

Letzte Beiträge

  • Von IONOS Zu Cloudflare Pages — Ein Migrations-Bericht
  • AIO in Der Praxis — Artificial Intelligence Optimization Schritt Für Schritt
  • AIO, GEO, LLMO, GAIO & SEO — Das Glossar
  • GAIO in Der Praxis — Generative AI Optimization Als Marketing-Begriff
  • GEO in Der Praxis — Generative Engine Optimization Für Perplexity & Co.
  • LLMO in Der Praxis — Large Language Model Optimization Für ChatGPT, Claude & Gemini
  • SEO in Der Praxis — Was 2026 Wirklich Zählt
© 2026 EinfachAleks  /  Impressum  /  Datenschutz
  1. Startseite
  2. diy
  3. Von IONOS Zu Cloudflare Pages — Ein Migrations-Bericht