TL;DR — Kurzzusammenfassung
Cloudflare Workers führt JavaScript am Edge mit V8-Isolates aus. Worker mit Wrangler deployen, KV-Storage, Secrets und GitHub Actions CI/CD einrichten.
Cloudflare Workers bringt serverloses Computing an den Edge — Ihr Code läuft in Rechenzentren in über 300 Städten weltweit, nur Millisekunden von Ihren Nutzern entfernt, ohne Server-Provisionierung oder Skalierungsaufwand. Auf V8-Isolates aufgebaut (derselbe Engine, der Chrome und Node.js antreibt), erreicht Workers Cold-Start-Zeiten unter 1 Millisekunde und ist damit dramatisch schneller als traditionelle containerbasierte serverlose Funktionen. In diesem Leitfaden gehen Sie von null zu einem vollständig in der Produktion deplooten Worker mit KV-Speicher, verschlüsselten Secrets, benutzerdefinierten Domains und einer automatisierten GitHub Actions-Deployment-Pipeline.
Voraussetzungen
- Node.js 18+ lokal installiert
- Ein Cloudflare-Konto (der kostenlose Plan funktioniert für alles in diesem Leitfaden)
- Grundlegende Kenntnisse in JavaScript oder TypeScript
- Eine registrierte Domain, die zu Cloudflare hinzugefügt wurde (nur für den Abschnitt benutzerdefinierte Domain erforderlich)
- npm oder pnpm als Paketmanager
Ihren Ersten Worker Erstellen
Installieren Sie Wrangler, Cloudflares offizielle CLI, global:
npm install -g wrangler
wrangler login
Der Befehl wrangler login öffnet ein Browserfenster und fragt nach der Autorisierung für Wrangler, auf Ihr Cloudflare-Konto zuzugreifen. Nach der Autorisierung werden Anmeldedaten in ~/.wrangler/config/default.toml gespeichert.
Erstellen Sie ein neues Projekt:
wrangler init my-api-worker
cd my-api-worker
Wrangler stellt einige Fragen — wählen Sie TypeScript und das “Hello World” Worker-Template. Die resultierende Verzeichnisstruktur ist:
my-api-worker/
src/
index.ts ← Ihr Worker-Code
wrangler.toml ← Projektkonfiguration
package.json
tsconfig.json
wrangler.toml Verstehen
Die Datei wrangler.toml ist das Projektmanifest. Eine minimale Konfiguration sieht so aus:
name = "my-api-worker"
main = "src/index.ts"
compatibility_date = "2024-09-23"
[[routes]]
pattern = "api.example.com/*"
zone_name = "example.com"
Schlüsselfelder:
| Feld | Zweck |
|---|---|
name | Worker-Name im Dashboard angezeigt |
main | Einstiegspunkt-Datei, von Wrangler aufgelöst |
compatibility_date | Fixiert das Runtime-API-Verhalten auf ein bestimmtes Datum |
routes | Mappt URL-Muster auf diesen Worker |
[[kv_namespaces]] | Bindet KV-Namespaces als Umgebungsvariablen |
[vars] | Klartext-Umgebungsvariablen |
Das compatibility_date ist wichtig — Cloudflare führt gelegentlich breaking changes in Worker-APIs ein, und dieses Datum legt fest, welchen API-Satz Ihr Worker sieht. Setzen Sie es immer auf das Erstellungsdatum und aktualisieren Sie es explizit nach der Prüfung des Changelogs.
Den Worker Schreiben
Der Worker-Einstiegspunkt exportiert ein Standard-Objekt mit einem fetch-Handler. Jede eingehende HTTP-Anfrage ruft diesen Handler auf:
export interface Env {
MY_KV: KVNamespace;
API_SECRET: string;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
// Route: JSON zurückgeben
if (url.pathname === '/api/status') {
return Response.json({ status: 'ok', region: request.cf?.colo });
}
// Route: HTML zurückgeben
if (url.pathname === '/') {
return new Response(
`<h1>Hallo vom Edge!</h1>`,
{ headers: { 'Content-Type': 'text/html;charset=UTF-8' } }
);
}
return new Response('Nicht Gefunden', { status: 404 });
}
};
Request- und Response-Muster
Workers verwendet die Standard-Fetch-API — Request, Response und Headers sind identisch mit Browser-APIs. Das bedeutet, dass Code, den Sie für Workers schreiben, weitgehend portierbar ist.
JSON zurückgeben ist idiomatisch mit Response.json():
return Response.json({ items: ['a', 'b', 'c'] }, {
headers: { 'Cache-Control': 'public, max-age=60' }
});
Eine Anfrage weiterleiten:
return Response.redirect('https://example.com/neuer-pfad', 301);
Eine proxied Response modifizieren (das “Transform”-Muster):
const upstream = await fetch(request);
const body = await upstream.text();
return new Response(body.replace('alter Text', 'neuer Text'), upstream);
Lokale Entwicklung
Starten Sie den lokalen Entwicklungsserver:
wrangler dev
Wrangler startet einen lokalen Server unter http://localhost:8787, der die Cloudflare-Runtime einschließlich KV, Durable Objects, R2 und dem request.cf-Metadaten-Objekt emuliert. Hot-Reload wird bei Dateiänderungen automatisch ausgelöst.
Zum Testen gegen die echte Cloudflare-Infrastruktur:
wrangler dev --remote
Inspizieren Sie Live-Traffic mit dem integrierten Tail-Log in einem zweiten Terminal:
wrangler tail
In die Produktion Deployen
Deployen Sie mit einem einzigen Befehl:
wrangler deploy
Wrangler kompiliert Ihr TypeScript, bündelt Abhängigkeiten und lädt den Worker in Cloudflares Netzwerk hoch. Das Deployment propagiert sich innerhalb von Sekunden global. Die Ausgabe enthält die workers.dev-URL:
Published my-api-worker (2.45 sec)
https://my-api-worker.ihre-subdomain.workers.dev
Benutzerdefinierte Domain Verbinden
Fügen Sie einen routes-Block in wrangler.toml hinzu, um Anfragen von Ihrer Cloudflare-proxied Domain an den Worker weiterzuleiten:
[[routes]]
pattern = "api.example.com/*"
zone_name = "example.com"
Alternativ nutzen Sie die Custom Domains-Funktion:
[[routes]]
pattern = "api.example.com"
custom_domain = true
Custom Domains stellt automatisch ein TLS-Zertifikat bereit und verwaltet das gesamte Routing.
Umgebungsvariablen und Secrets
Einfache Variablen
Nicht-sensible Konfiguration lebt in wrangler.toml:
[vars]
ENVIRONMENT = "production"
MAX_RETRIES = "3"
Greifen Sie im Worker als env.ENVIRONMENT und env.MAX_RETRIES darauf zu.
Verschlüsselte Secrets
Secrets werden im Ruhezustand verschlüsselt und sind nach dem Upload nie sichtbar. Fügen Sie sie per CLI hinzu:
wrangler secret put API_KEY
Wrangler fordert Sie auf, den Wert interaktiv einzugeben. Vorhandene Secrets auflisten:
wrangler secret list
Im Worker erscheinen Secrets als env.API_KEY — zur Laufzeit nicht von einfachen Variablen zu unterscheiden, aber in Cloudflares Vault verschlüsselt gespeichert.
KV-Speicher
KV (Workers KV) ist ein global verteilter Schlüssel-Wert-Speicher mit eventueller Konsistenz. Er eignet sich hervorragend zum Speichern von Konfigurationen, Benutzersitzungen, gecachten API-Antworten und Feature-Flags.
Erstellen Sie einen KV-Namespace:
wrangler kv namespace create CACHE
Wrangler gibt die Namespace-ID aus. Fügen Sie das Binding zu wrangler.toml hinzu:
[[kv_namespaces]]
binding = "CACHE"
id = "abc123def456..."
Im Worker schreiben und lesen:
// Schreiben (mit optionalem TTL in Sekunden)
await env.CACHE.put('benutzer:123', JSON.stringify(benutzerdaten), { expirationTtl: 3600 });
// Lesen
const raw = await env.CACHE.get('benutzer:123');
const benutzer = raw ? JSON.parse(raw) : null;
// Löschen
await env.CACHE.delete('benutzer:123');
Vergleich
| Merkmal | Cloudflare Workers | AWS Lambda@Edge | Deno Deploy |
|---|---|---|---|
| Runtime | V8-Isolates | Node.js-Container | V8-Isolates |
| Cold Start | < 1 ms | 100–500 ms | ~50 ms |
| Globale PoPs | 300+ | ~4 CloudFront-Regionen | 35 Regionen |
| Kostenloser Plan | 100k Req/Tag | Bezahlung pro Anfrage | 100k Req/Tag |
| Max. CPU-Zeit | 50 ms (kostenlos) / 30 s (bezahlt) | 30 s | 50 ms |
| Speicher | KV, R2, D1, Durable Objects | DynamoDB (separat) | Deno KV |
| TypeScript | Nativ (eingebaut) | Per Build-Schritt | Nativ |
| Preis (über kostenlos) | 0,50$/Mio. Anfragen | ~0,60$/Mio. + Lambda | 0,50$/Mio. Anfragen |
Workers gewinnt bei Cold Start und globaler Verteilung. Lambda@Edge ist die richtige Wahl, wenn Sie bereits tief im AWS-Ökosystem verwurzelt sind. Deno Deploy ist eine gute Alternative, wenn Sie Denos Berechtigungsmodell bevorzugen.
Praxisbeispiel: API-Proxy-Worker
Sie haben eine Drittanbieter-API, die kein CORS unterstützt, einen API-Key erfordert, den Sie dem Browser nicht preisgeben können, und mit Daten antwortet, die Sie cachen und transformieren möchten. Ein Cloudflare Worker ist die ideale Lösung.
export interface Env {
UPSTREAM_API_KEY: string;
CACHE: KVNamespace;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
const upstreamUrl = `https://api.drittanbieter.com${url.pathname}${url.search}`;
const cacheKey = upstreamUrl;
// Zuerst KV-Cache prüfen
const cached = await env.CACHE.get(cacheKey);
if (cached) {
return Response.json(JSON.parse(cached), {
headers: { 'X-Cache': 'HIT', 'Access-Control-Allow-Origin': '*' }
});
}
// Vom Upstream mit geheimem Schlüssel abrufen
const upstream = await fetch(upstreamUrl, {
headers: { 'Authorization': `Bearer ${env.UPSTREAM_API_KEY}` }
});
if (!upstream.ok) {
return new Response('Upstream-Fehler', { status: upstream.status });
}
const data = await upstream.json();
// Antwort für 5 Minuten cachen
ctx.waitUntil(env.CACHE.put(cacheKey, JSON.stringify(data), { expirationTtl: 300 }));
return Response.json(data, {
headers: { 'X-Cache': 'MISS', 'Access-Control-Allow-Origin': '*' }
});
}
};
Dieser Worker hält den API-Key serverseitig, fügt fehlende CORS-Header hinzu und liefert gecachte Antworten von den Edge-Standorten, die dem jeweiligen Nutzer am nächsten sind.
CI/CD mit GitHub Actions
Automatisieren Sie Deployments bei jedem Push nach main:
# .github/workflows/deploy.yml
name: Deploy Worker
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@v4
- name: Node.js einrichten
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Abhängigkeiten installieren
run: npm ci
- name: Auf Cloudflare Workers deployen
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
Fügen Sie CF_API_TOKEN und CLOUDFLARE_ACCOUNT_ID als Repository-Secrets in GitHub hinzu. Erstellen Sie den API-Token im Cloudflare-Dashboard unter Profil → API-Token → Token erstellen mit der “Edit Cloudflare Workers”-Vorlage.
Stolperfallen und Sonderfälle
CPU-Zeitlimit — Der kostenlose Plan erlaubt 10 ms CPU-Zeit pro Anfrage. Der Workers Paid-Plan erhöht dies auf 30 Sekunden. CPU-intensive Arbeit kann dieses Limit erreichen; lagern Sie schwere Berechnungen in eine Queue aus oder nutzen Sie Durable Objects.
Subanfragen-Limits — Jeder Worker-Aufruf kann im kostenlosen Plan bis zu 50 ausgehende fetch()-Aufrufe tätigen (1000 im bezahlten Plan).
Kompatibilitätsdatum und Breaking Changes — Prüfen Sie beim Aktualisieren von compatibility_date das Changelog der Kompatibilitäts-Flags sorgfältig.
Größenlimits — Worker-Skripte sind auf 1 MB nach Komprimierung begrenzt (10 MB im bezahlten Plan). Große npm-Abhängigkeiten können dieses Limit überschreiten; nutzen Sie Tree Shaking.
Kein Dateisystemzugriff — Workers haben keine Disk-I/O. Alle Persistenz muss über KV, R2, D1 oder Durable Objects laufen.
waitUntil für Hintergrundarbeit — Verwenden Sie ctx.waitUntil(promise) für Arbeit, die nach dem Senden der Antwort abgeschlossen werden soll (wie Cache-Schreibvorgänge).
Fehlerbehebung
Error: Script startup exceeded CPU time limit — Ihr Worker führt teure Operationen während der Modulinitialisierung durch. Verlagern Sie teure Operationen in den Handler oder nutzen Sie lazy Initialisierung.
TypeError: Cannot read properties of undefined (reading 'get') — Ein KV- oder anderes Binding fehlt in wrangler.toml, oder Sie greifen auf env.MEIN_BINDING zu, bevor das Binding konfiguriert ist.
wrangler deploy schlägt mit “Authentication error” fehl — Ihre Wrangler-Sitzung ist abgelaufen. Führen Sie wrangler login erneut aus oder setzen Sie die Umgebungsvariable CLOUDFLARE_API_TOKEN.
CORS-Fehler im Browser — Der Worker-Antwort fehlt Access-Control-Allow-Origin. Fügen Sie den Header im Response-Konstruktor hinzu. Behandeln Sie auch die OPTIONS-Preflight-Anfrage separat.
Benutzerdefinierte Domain leitet nicht zum Worker — Stellen Sie sicher, dass die Domain über Cloudflare proxied wird (orangefarbene Wolke in DNS-Einstellungen), das Routen-Muster in wrangler.toml das /*-Wildcard verwendet, und Sie nach der Änderung von wrangler.toml neu deployed haben.
Zusammenfassung
- Cloudflare Workers sind serverlose Funktionen auf V8-Isolate-Basis, die am Edge mit sub-millisekunden Cold Starts und globaler Verteilung laufen
- Installieren Sie Wrangler mit
npm install -g wrangler, erstellen Sie das Gerüst mitwrangler initund testen Sie lokal mitwrangler dev - Die Datei
wrangler.tomlsteuert Worker-Name, Einstiegspunkt, Kompatibilitätsdatum, Routen und alle Ressource-Bindings - Verwenden Sie
wrangler secret putfür sensible Werte und[vars]inwrangler.tomlfür nicht-sensible Konfiguration - KV-Namespaces bieten global verteilten Schlüssel-Wert-Speicher, zugänglich über
env.BINDING.get/put/delete - Workers übertrifft Lambda@Edge bei Cold Start und globaler Reichweite; Lambda@Edge ist bei tiefer AWS-Ökosystem-Integration zu bevorzugen
- Die
wrangler-actionGitHub Action bietet schlüsselfertiges CI/CD; beschränken Sie Ihren API-Token auf Workers-Berechtigungen - Beachten Sie CPU-Zeitlimits, Subanfragen-Obergrenzen und die 1-MB-Skriptgrößengrenze im kostenlosen Plan