EmDash speichert hochgeladene Medien (Bilder, Dokumente, Videos) in einem konfigurierbaren Speicher-Backend. Wählen Sie basierend auf Ihrer Deployment-Plattform und Ihren Anforderungen.
Überblick
| Speicher | Ideal für | Funktionen |
|---|---|---|
| R2 Binding | Cloudflare Workers | Keine Konfiguration, schnell |
| S3 | Jede Plattform | Signierte Uploads, CDN-Support |
| Lokal | Entwicklung | Einfacher Dateisystemspeicher |
Cloudflare R2 (Binding)
Verwenden Sie R2-Bindings für die schnellste Integration beim Deployment auf Cloudflare Workers.
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 des Buckets |
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:
- Cloudflare Dashboard > R2 > Ihr Bucket
- Öffentlichen Zugriff in den Einstellungen aktivieren
- Öffentliche URL zur Konfiguration hinzufügen:
storage: r2({
binding: "MEDIA",
publicUrl: "https://pub-xxxx.r2.dev",
});
S3-kompatibler Speicher
Der S3-Adapter funktioniert mit Cloudflare R2 (über die S3-API), MinIO und anderen S3-kompatiblen Diensten.
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-Endpunkt-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 |
* accessKeyId und secretAccessKey müssen gemeinsam 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 die
Anmeldedaten 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.
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
// s3() with no args: all fields from S3_* environment variables
storage: s3(),
// Or mix: override one field, rest from environment
// storage: s3({ publicUrl: "https://cdn.example.com" }),
}),
],
});
R2 über die S3-API
Verwenden Sie S3-Anmeldedaten 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-Anmeldedaten im Cloudflare Dashboard unter R2 > Manage R2 API Tokens.
MinIO
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 lokalen Speicher 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 Dateispeicher |
baseUrl | string | Basis-URL zum Bereitstellen von Dateien |
Die baseUrl sollte mit EmDashs Medien-Datei-Endpunkt (/_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, 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 verfügbar, 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 die S3-API)
Adapter, die signierte Uploads nicht unterstützen:
- R2 Binding (verwenden Sie stattdessen den S3-Adapter mit R2-Anmeldedaten)
- Lokal
Speicher-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 den Wechsel des Speicher-Backends, ohne den Anwendungscode zu ändern.