EmDash speichert hochgeladene Medien (Bilder, Dokumente, Videos) in einem konfigurierbaren Speicher-Backend. Wählen Sie je nach Ihrer Deployment-Plattform und Ihren Anforderungen.
Überblick
| Speicher | Am besten für | Funktionen |
|---|---|---|
| R2 Binding | Cloudflare Workers | Zero-Config, schnell |
| S3 | Jede Plattform | Signed Uploads, CDN-Support |
| Local | Entwicklung | Einfache 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
| 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
Für öffentliche Medien-URLs aktivieren Sie den öffentlichen Zugriff auf Ihren R2-Bucket:
- Gehen Sie zum Cloudflare Dashboard > R2 > Ihr Bucket
- Aktivieren Sie den öffentlichen Zugriff unter Einstellungen
- 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
| Option | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
endpoint | string | ja | S3-Endpoint-URL |
bucket | string | ja | Bucket-Name |
accessKeyId | string | nein* | Access Key |
secretAccessKey | string | nein* | Secret Key |
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.
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.
| 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 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
| Option | Typ | Beschreibung |
|---|---|---|
directory | string | Verzeichnispfad für Dateispeicherung |
baseUrl | string | Basis-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.