Speicheroptionen

Auf dieser Seite

EmDash speichert hochgeladene Medien (Bilder, Dokumente, Videos) in einem konfigurierbaren Speicher-Backend. Wählen Sie je nach Ihrer Deployment-Plattform und Ihren Anforderungen.

Überblick

SpeicherAm besten fürFunktionen
R2 BindingCloudflare WorkersZero-Config, schnell
S3Jede PlattformSigned Uploads, CDN-Support
LocalEntwicklungEinfache Dateispeicherung

Cloudflare R2 (Binding)

Verwenden Sie R2-Bindings beim Deployment auf Cloudflare Workers für die schnellste Integration.

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

Für öffentliche Medien-URLs aktivieren Sie den öffentlichen Zugriff auf Ihren R2-Bucket:

  1. Gehen Sie zum Cloudflare Dashboard > R2 > Ihr Bucket
  2. Aktivieren Sie den öffentlichen Zugriff unter Einstellungen
  3. Fügen Sie die öffentliche URL zu Ihrer Konfiguration hinzu:
storage: r2({
	binding: "MEDIA",
	publicUrl: "https://pub-xxxx.r2.dev",
});

S3-kompatible Speicherung

Der S3-Adapter funktioniert mit Cloudflare R2 (über S3 API), MinIO und anderen S3-kompatiblen Diensten.

Die folgende Konfiguration richtet EmDash auf einen S3-kompatiblen Bucket aus:

import emdash, { s3 } from "emdash/astro";

export default defineConfig({
	integrations: [
		emdash({
			storage: s3({
				endpoint: process.env.S3_ENDPOINT,
				bucket: process.env.S3_BUCKET,
				accessKeyId: process.env.S3_ACCESS_KEY_ID,
				secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
				region: "auto", // Optional, defaults to "auto"
				publicUrl: process.env.S3_PUBLIC_URL, // Optional CDN URL
			}),
		}),
	],
});

Konfiguration

OptionTypErforderlichBeschreibung
endpointstringjaS3-Endpoint-URL
bucketstringjaBucket-Name
accessKeyIdstringnein*Access Key
secretAccessKeystringnein*Secret Key
regionstringneinRegion (Standard: "auto")
publicUrlstringneinOptionale CDN oder öffentliche URL

* Sowohl accessKeyId als auch secretAccessKey müssen zusammen angegeben oder beide weggelassen werden.

Auflösung der S3-Konfiguration aus Umgebungsvariablen

Jedes Feld, das in s3({...}) weggelassen wird, wird aus der entsprechenden S3_* Umgebungsvariablen gelesen, wenn der Prozess startet. Dies ermöglicht es Ihnen, ein Container-Image einmal zu erstellen und Zugangsdaten beim Start ohne Rebuild einzufügen. 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 aus process.env gelesen, wenn der Prozess startet. 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 gemischt: ein Feld überschreiben, Rest aus Umgebung
			// storage: s3({ publicUrl: "https://cdn.example.com" }),
		}),
	],
});

R2 über S3 API

Verwenden Sie S3-Zugangsdaten mit R2 für Funktionen wie signierte Upload-URLs:

storage: s3({
	endpoint: "https://<account-id>.r2.cloudflarestorage.com",
	bucket: "emdash-media",
	accessKeyId: process.env.R2_ACCESS_KEY_ID,
	secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
	publicUrl: "https://pub-xxxx.r2.dev",
});

Generieren Sie R2 API-Zugangsdaten im Cloudflare-Dashboard unter R2 > Manage R2 API Tokens.

MinIO

Richten Sie den S3-Adapter auf einen MinIO-Endpoint mit seinen Zugangsdaten aus:

storage: s3({
	endpoint: "https://minio.example.com",
	bucket: "emdash-media",
	accessKeyId: process.env.MINIO_ACCESS_KEY,
	secretAccessKey: process.env.MINIO_SECRET_KEY,
	publicUrl: "https://minio.example.com/emdash-media",
});

Lokales Dateisystem

Verwenden Sie lokale Speicherung für die Entwicklung. Dateien werden in einem Verzeichnis auf der 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 Dateispeicherung
baseUrlstringBasis-URL für das 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.

Umgebungsbasierte Konfiguration

Wechseln Sie Speicher-Backends basierend auf der Umgebung:

import emdash, { s3, 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, sodass Clients direkt zum Speicher hochladen können, ohne über Ihren Server zu gehen. Dies verbessert die Leistung für große Dateien.

Signierte Uploads sind automatisch bei Verwendung des S3-Adapters. Das Admin-Interface verwendet 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 S3-Adapter mit R2-Zugangsdaten)
  • Local

Storage-Interface

Alle Speicher-Adapter implementieren dasselbe 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 das Wechseln von Speicher-Backends ohne Änderung des Anwendungscodes.