Wählen Sie einen Speicheradapter für hochgeladene Medien. Eine Datenbanksicherung enthält Medienmetadaten, nicht die gespeicherten Dateien, sichern Sie also das Speicher-Backend separat.
Übersicht
| Speicher | Verwenden wenn | Signierte Uploads |
|---|---|---|
| R2 Binding | Die Website läuft auf Cloudflare Workers | Nein |
| S3 | Eine Node.js-Website nutzt AWS S3, R2’s S3 API, MinIO oder kompatiblen Speicher | Ja |
| Lokal | Eine Node.js-Website hat ein beschreibbares persistentes Volume | Nein |
Cloudflare R2 Binding
Verwenden Sie den R2-Binding-Adapter auf Cloudflare Workers. Das Binding stellt Zugriff zur Laufzeit bereit, sodass die Website keine R2-Zugriffsschlüssel benötigt.
import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
storage: r2({ binding: "MEDIA" }),
}),
],
});
Konfiguration
| Option | Typ | Beschreibung |
|---|---|---|
binding | string | R2-Binding-Name aus wrangler.jsonc |
publicUrl | string | Optionale öffentliche URL für den Bucket |
Einrichtung
Fügen Sie das R2-Binding zu Ihrer Wrangler-Konfiguration hinzu:
wrangler.jsonc
{
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "emdash-media"
}
]
} wrangler.toml
[[r2_buckets]]
binding = "MEDIA"
bucket_name = "emdash-media" Öffentlicher Zugriff
Um Medien von einem öffentlichen Bucket bereitzustellen, verbinden Sie eine benutzerdefinierte Domain mit der Cloudflare API und setzen Sie deren Origin als publicUrl. Cloudflares r2.dev-Entwicklungs-URL ist ratenbegrenzt und nicht für Produktionstraffic gedacht.
storage: r2({
binding: "MEDIA",
publicUrl: "https://media.example.com",
});
Wenn derselbe Bucket automatische JSON-Backups speichert, kann ein öffentlicher Bucket-Origin Objekte unter backups/ offenlegen. Verwenden Sie einen privaten Bucket und EmDashs Medienroute oder beschränken Sie den öffentlichen Origin auf Medienobjekte. Siehe Backups.
S3-kompatibler Speicher
Der S3-Adapter funktioniert unter Node.js mit Cloudflare R2’s S3 API, AWS S3, MinIO und kompatiblen Diensten.
Die folgende Konfiguration löst Endpoint, Bucket, Credentials, Region und optionale öffentliche URL aus S3_*-Variablen auf, wenn der Node.js-Prozess startet:
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: s3(),
}),
],
});
Konfiguration
| Option | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
endpoint | string | ja | S3-Endpoint-URL |
bucket | string | ja | Bucket-Name |
accessKeyId | string | nein* | Zugriffsschlüssel |
secretAccessKey | string | nein* | Geheimer Schlüssel |
region | string | nein | Region (Standard: "auto") |
publicUrl | string | nein | Optionale CDN- oder öffentliche URL |
* Sowohl accessKeyId als auch secretAccessKey müssen zusammen angegeben oder beide weggelassen werden.
S3-Konfiguration aus Umgebungsvariablen auflösen
Jedes in s3({...}) ausgelassene Feld wird beim Prozessstart aus der entsprechenden S3_*-Umgebungsvariable gelesen. So können Sie ein Container-Image einmal bauen und Credentials beim Start injizieren, ohne neu zu bauen. Explizite Werte in s3({...}) haben immer Vorrang vor Umgebungsvariablen.
| Umgebungsvariable | Feld | Hinweise |
|---|---|---|
S3_ENDPOINT | endpoint | Muss eine gültige http/https-URL sein |
S3_BUCKET | bucket | |
S3_ACCESS_KEY_ID | accessKeyId | |
S3_SECRET_ACCESS_KEY | secretAccessKey | |
S3_REGION | region | Standard: "auto" |
S3_PUBLIC_URL | publicUrl | Optionales CDN-Präfix |
Umgebungsvariablen werden beim Prozessstart aus process.env gelesen. Dies ist eine reine Node-Funktion.
Der Aufruf von s3() ohne Argumente liest jedes Feld aus den S3_*-Umgebungsvariablen:
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
// s3() ohne Argumente: alle Felder aus S3_*-Umgebungsvariablen
storage: s3(),
// Oder mischen: ein Feld überschreiben, Rest aus der Umgebung
// storage: s3({ publicUrl: "https://cdn.example.com" }),
}),
],
});
R2 über S3 API
Verwenden Sie den S3-Adapter unter Node.js, wenn direkte signierte Uploads zu R2 erforderlich sind. Erstellen Sie begrenzte R2 API-Credentials mit der Cloudflare API oder CLI und setzen Sie dann die folgenden Laufzeitvariablen:
S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
S3_BUCKET=emdash-media
S3_ACCESS_KEY_ID=<r2-access-key-id>
S3_SECRET_ACCESS_KEY=<r2-secret-access-key>
S3_REGION=auto
S3_PUBLIC_URL=https://media.example.com
Bewahren Sie die echten Werte im Secret Manager der Node.js-Hosting-Plattform auf. Die öffentliche URL ist optional und ersetzt nicht den S3 API-Endpoint, der für Uploads verwendet wird.
MinIO
Richten Sie die gleichen Laufzeitvariablen auf MinIO. Setzen Sie S3_ENDPOINT auf den MinIO API-Origin, S3_BUCKET auf den Bucket-Namen und die beiden Credential-Variablen auf einen begrenzten MinIO-Zugriffsschlüssel. Setzen Sie S3_PUBLIC_URL nur, wenn dieser Origin die Objekte des Buckets öffentlich bereitstellt.
Lokales Dateisystem
Verwenden Sie lokalen Speicher für die Entwicklung oder einen einzelnen Node.js-Server mit persistenter Festplatte. Dateien werden in einem Verzeichnis auf dieser Festplatte gespeichert.
import emdash, { local } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});
Konfiguration
| Option | Typ | Beschreibung |
|---|---|---|
directory | string | Verzeichnispfad für Dateispeicher |
baseUrl | string | Basis-URL zum Bereitstellen von Dateien |
Die baseUrl sollte mit EmDashs Medien-Datei-Endpoint (/_emdash/api/media/file) übereinstimmen, es sei denn, Sie konfigurieren einen benutzerdefinierten statischen Dateiserver.
Separaten Speicher für verschiedene Umgebungen verwenden
Die folgende Konfiguration verwendet während der Entwicklung ein lokales Verzeichnis und R2 im Cloudflare-Produktions-Build:
import emdash, { local } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
const storage = import.meta.env.PROD
? r2({ binding: "MEDIA" })
: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
});
export default defineConfig({
integrations: [emdash({ storage })],
});
Signierte Uploads
Der S3-Adapter unterstützt signierte Upload-URLs, die es Clients ermöglichen, direkt in den Speicher hochzuladen, ohne über Ihren Server zu gehen. Dies verbessert die Leistung bei großen Dateien.
Signierte Uploads sind automatisch, wenn der S3-Adapter verwendet wird. Die Admin-Oberfläche nutzt sie, wenn verfügbar.
Adapter, die signierte Uploads unterstützen:
- S3 (einschließlich R2 über S3 API)
Adapter, die keine signierten Uploads unterstützen:
- R2 Binding (verwenden Sie stattdessen den S3-Adapter mit R2-Credentials)
- Lokal
Speicher-Interface
Alle Speicheradapter implementieren das gleiche Interface:
interface Storage {
upload(options: {
key: string;
body: Buffer | Uint8Array | ReadableStream;
contentType: string;
}): Promise<UploadResult>;
download(key: string): Promise<DownloadResult>;
delete(key: string): Promise<void>;
exists(key: string): Promise<boolean>;
list(options?: ListOptions): Promise<ListResult>;
getSignedUploadUrl(options: SignedUploadOptions): Promise<SignedUploadUrl>;
getPublicUrl(key: string): string;
}
Diese Konsistenz ermöglicht den Wechsel von Speicher-Backends, ohne den Anwendungscode zu ändern.