Medienspeicher wählen

Auf dieser Seite

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

SpeicherVerwenden wennSignierte Uploads
R2 BindingDie Website läuft auf Cloudflare WorkersNein
S3Eine Node.js-Website nutzt AWS S3, R2’s S3 API, MinIO oder kompatiblen SpeicherJa
LokalEine Node.js-Website hat ein beschreibbares persistentes VolumeNein

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

OptionTypBeschreibung
bindingstringR2-Binding-Name aus wrangler.jsonc
publicUrlstringOptionale ö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

OptionTypErforderlichBeschreibung
endpointstringjaS3-Endpoint-URL
bucketstringjaBucket-Name
accessKeyIdstringnein*Zugriffsschlüssel
secretAccessKeystringnein*Geheimer Schlüssel
regionstringneinRegion (Standard: "auto")
publicUrlstringneinOptionale 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.

UmgebungsvariableFeldHinweise
S3_ENDPOINTendpointMuss eine gültige http/https-URL sein
S3_BUCKETbucket
S3_ACCESS_KEY_IDaccessKeyId
S3_SECRET_ACCESS_KEYsecretAccessKey
S3_REGIONregionStandard: "auto"
S3_PUBLIC_URLpublicUrlOptionales 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

OptionTypBeschreibung
directorystringVerzeichnispfad für Dateispeicher
baseUrlstringBasis-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.