Bereitstellung auf Cloudflare

Auf dieser Seite

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:

  1. Gehen Sie zu Workers & Pages > Ihr Worker
  2. Klicken Sie auf Custom Domains > Add Custom Domain
  3. 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):

  1. Gehen Sie im Cloudflare-Dashboard zu R2 > Ihr Bucket
  2. Klicken Sie auf Settings > Public access
  3. Aktivieren Sie den öffentlichen Zugriff und notieren Sie die öffentliche URL
  4. 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.

VariableZweck
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_SECRETOptional. 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.