Cloudflare Workers bietet eine schnelle, global verteilte Laufzeitumgebung für EmDash. Diese Anleitung behandelt die Bereitstellung mit D1 für die Datenbank und R2 für die Medienspeicherung.
Voraussetzungen
- Ein Cloudflare-Konto
- Wrangler CLI installiert (
npm install -g wrangler) - Mit Cloudflare authentifiziert (
wrangler login)
Bindings konfigurieren
Erstellen Sie wrangler.jsonc im Projektstammverzeichnis mit D1- und R2-Bindings. Wrangler stellt beide Ressourcen beim ersten Deployment automatisch bereit, wenn sie noch nicht existieren.
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-emdash-site",
"compatibility_date": "2025-01-15",
"compatibility_flags": ["nodejs_compat"],
"d1_databases": [
{
"binding": "DB",
"database_name": "emdash-db",
},
],
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "emdash-media",
},
],
}
EmDash konfigurieren
Aktualisieren Sie Ihre Astro-Konfiguration, um D1 und R2 zu verwenden:
import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import emdash from "emdash/astro";
import { d1, r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
output: "server",
adapter: cloudflare(),
integrations: [
emdash({
database: d1({ binding: "DB" }),
storage: r2({ binding: "MEDIA" }),
}),
],
});
Erster Start
Datenbankmigrationen werden automatisch bei der ersten Anfrage nach dem Deployment ausgeführt und bei jedem nachfolgenden Start, wenn es etwas Neues anzuwenden gibt.
Wenn die Datenbank leer ist (keine Collections) und der Einrichtungsassistent nicht abgeschlossen wurde, wendet EmDash beim ersten Start auch eine Seed-Datei an. Der Seed wird zur Build-Zeit aus .emdash/seed.json, dem Pfad in package.json#emdash.seed oder seed/seed.json gelesen — je nachdem, was zuerst gefunden wird — und in das Bundle eingebettet. Wenn keine vorhanden ist, wird ein integrierter Standard-Seed verwendet. Nachfolgende Deployments gegen eine bestehende Datenbank lassen deren Inhalt unverändert.
Bereitstellen
Auf Cloudflare Workers bereitstellen:
wrangler deploy
Ihre Website ist jetzt live unter https://my-emdash-site.<your-subdomain>.workers.dev.
Read Replicas
Für global verteilte Websites aktivieren Sie die D1-Lesereplikation, um Leseabfragen an nahegelegene Replikas weiterzuleiten, anstatt immer die primäre Datenbank zu verwenden. Dies reduziert die Latenz für Besucher, die weit von der primären Region entfernt sind, erheblich.
emdash({
database: d1({
binding: "DB",
session: "auto",
}),
storage: r2({ binding: "MEDIA" }),
}),
Sie müssen auch die Lesereplikation für die D1-Datenbank selbst im Cloudflare-Dashboard oder über die REST-API aktivieren.
Siehe Datenbankoptionen — Read Replicas für Sitzungsmodi und wie lesezeichen-basierte Konsistenz funktioniert.
Custom Domain
Fügen Sie eine benutzerdefinierte Domain im Cloudflare-Dashboard hinzu:
- Gehen Sie zu Workers & Pages > Ihr Worker
- Klicken Sie auf Custom Domains > Add Custom Domain
- Geben Sie Ihre Domain ein und befolgen Sie die DNS-Setup-Anweisungen
Öffentlicher R2-Zugriff
Um Medien direkt von R2 bereitzustellen (empfohlen für die Performance):
- Gehen Sie im Cloudflare-Dashboard zu R2 > Ihr Bucket
- Klicken Sie auf Settings > Public access
- Aktivieren Sie den öffentlichen Zugriff und notieren Sie die öffentliche URL
- Aktualisieren Sie Ihre Speicherkonfiguration:
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxx.r2.dev"
}),
Cloudflare Access-Authentifizierung
Wenn Ihre Organisation Cloudflare Access verwendet, können Sie es als Authentifizierungsanbieter anstelle von Passkeys verwenden und so Single Sign-On über Ihren bestehenden Identity Provider ermöglichen. Die folgende Konfiguration aktiviert dies:
emdash({
database: d1({ binding: "DB" }),
storage: r2({ binding: "MEDIA" }),
auth: access({
teamDomain: "myteam.cloudflareaccess.com",
audience: "your-app-audience-tag",
roleMapping: {
"Admins": 50,
"Editors": 40,
},
}),
}),
Siehe den Authentifizierungsleitfaden für vollständige Konfigurationsoptionen.
Umgebungsvariablen
Empfohlen: Verschlüsselungsschlüssel
EMDASH_ENCRYPTION_KEY ist der Schlüssel zum Verschlüsseln von Plugin-Secrets im Ruhezustand (Webhook-Token, Turnstile-Schlüssel usw.). Der Schlüssel wird beim Start validiert; die Plugin-Secret-Verschlüsselung verwendet ihn, sobald sie aktiviert ist. Setzen Sie ihn bei jedem Deployment, damit Secrets ohne spätere Konfigurationsänderung geschützt sind.
Der Schlüssel wird von Ihnen bereitgestellt und niemals in der Datenbank gespeichert; nur verschlüsselter Chiffretext wird gespeichert. Ihn zu verlieren bedeutet, jedes damit verschlüsselte Secret zu verlieren.
Generieren Sie einen Schlüssel und speichern Sie ihn als Worker-Secret mit den folgenden Befehlen:
npx emdash secrets generate
wrangler secret put EMDASH_ENCRYPTION_KEY
Optional: Stabile Wert-Überschreibungen
EmDash generiert automatisch das Preview-HMAC-Secret und das Commenter-IP-Hash-Salt und speichert sie bei der ersten Verwendung in der Datenbank. Die unten aufgeführten Umgebungsvariablen sind Überschreibungen für Fälle, in denen Sie den Wert selbst festlegen müssen — zum Beispiel, wenn ein Preview-Worker in einem separaten Prozess das Secret mit Ihrer Hauptwebsite teilen muss.
| Variable | Zweck |
|---|---|
EMDASH_PREVIEW_SECRET | Überschreibung für das automatisch generierte Preview-HMAC-Secret. |
EMDASH_IP_SALT | Überschreibung für das automatisch generierte Commenter-IP-Hash-Salt. |
EMDASH_AUTH_SECRET | Optional. Wenn gesetzt, wird es als IP-Salt-Quelle verwendet (es sei denn, EMDASH_IP_SALT ist ebenfalls gesetzt, was Vorrang hat), wodurch Commenter-IP-Hashes für Installationen stabil bleiben, die bereits darauf angewiesen sind. Lassen Sie es für ein neues Deployment ungesetzt. |
Greifen Sie auf Umgebungsvariablen in Ihrer Konfiguration mit import.meta.env oder dem Cloudflare-env-Binding zu.
Preview-Deployments
Stellen Sie einen Preview-Branch bereit:
wrangler deploy --env preview
Fügen Sie einen Environment-Abschnitt zu wrangler.jsonc hinzu:
{
"env": {
"preview": {
"d1_databases": [
{
"binding": "DB",
"database_name": "emdash-db-preview",
},
],
},
},
}
Fehlerbehebung
”D1 binding not found”
Überprüfen Sie, ob der Binding-Name in wrangler.jsonc mit Ihrer Datenbankkonfiguration übereinstimmt:
// Must match: d1({ binding: "DB" })
"binding": "DB"
“R2 binding not found”
Überprüfen Sie, ob das R2-Bucket korrekt gebunden ist:
// Must match: r2({ binding: "MEDIA" })
"binding": "MEDIA"
Migrationsfehler
Wenn Sie Schema-Fehler sehen, verfolgen Sie die Worker-Logs (wrangler tail) und reproduzieren Sie den Fehler, um die zugrunde liegende Nachricht zu erfassen — reichen Sie dann ein Issue mit dieser Ausgabe ein.