Speicher
Konfigurieren Sie die zwei S3-kompatiblen Buckets für Avatare, Organisationslogos und Chat-Anhänge, einschließlich der CORS-Regel, die beide Buckets brauchen.
Cargo Marshal speichert hochgeladene Bilder in zwei S3-kompatiblen Buckets. Diese Seite richtet sich an Betreiber, die die App selbst hosten oder bereitstellen. Sie erklärt, was jeder Bucket enthält, und nennt die CORS-Regel, die beide Buckets brauchen.
Der öffentliche Bucket für Bilder
Der öffentliche Bucket enthält Avatare und Organisationslogos. Jeder, der die URL kennt, kann ein Objekt lesen. Die App liefert diese Dateien direkt von NEXT_PUBLIC_S3_PUBLIC_URL aus, und der Bucket-Name steht in NEXT_PUBLIC_S3_BUCKET_NAME_IMAGES. Sind beide Variablen nicht gesetzt, bleiben Uploads für Avatare und Logos sichtbar, aber deaktiviert.
Der private Bucket für Anhänge
Der private Bucket enthält Bild-Anhänge aus dem Chat. Er blockiert jeden öffentlichen Zugriff, und sein Name steht in S3_BUCKET_NAME_ATTACHMENTS. Die App prüft, ob der Betrachter den Chat lesen darf, und gibt dem Browser dann eine signierte GET-URL, die nach etwa 30 Minuten abläuft. Ist die Variable nicht gesetzt, sind Bild-Uploads im Chat deaktiviert. Verweisen Sie sie nie auf den öffentlichen Bucket für Bilder.
Beide Buckets nutzen dieselben Zugangsdaten (AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY) und denselben Endpunkt (AWS_ENDPOINT_URL_S3). Ist der Endpunkt nicht gesetzt, spricht die App mit AWS S3 in AWS_REGION. Setzen Sie AWS_S3_FORCE_PATH_STYLE=true, wenn Ihr Anbieter URLs im Path-Style braucht.
Erforderliche Bucket-Konfiguration
Der Browser lädt jede Datei mit einer vorsignierten PUT-Anfrage direkt in den Bucket hoch und lädt Chat-Anhänge mit einer signierten GET-Anfrage. Beides sind Anfragen über Ursprungsgrenzen hinweg, deshalb muss jeder Bucket den CORS-Preflight beantworten. Ein Bucket ohne CORS-Regel lehnt den Preflight ab, und der Upload schlägt fehl. R2 antwortet auf den Preflight mit 403.
Wenden Sie dieselbe Regel auf beide Buckets an. Tragen Sie jeden Origin ein, von dem die App ausgeliefert wird:
- Die Produktions-URL, mit und ohne
www, wenn beide erreichbar sind. - Jede URL einer Preview-Bereitstellung, zum Beispiel
https://cargomarshal-git-my-branch.vercel.app. http://localhost:3000für die lokale Arbeit.
Ein Origin besteht aus Schema, Host und Port, ohne Pfad und ohne abschließenden Schrägstrich.
Cloudflare R2
Öffnen Sie im Cloudflare-Dashboard den Bucket, gehen Sie zu Settings und fügen Sie eine CORS-Richtlinie mit diesem JSON hinzu. Sie können es auch an die R2-CORS-API senden.
{
"rules": [
{
"allowed": {
"origins": [
"https://www.cargomarshal.com",
"https://cargomarshal.com",
"http://localhost:3000"
],
"methods": ["GET", "HEAD", "PUT"],
"headers": ["*"]
},
"exposeHeaders": ["ETag"],
"maxAgeSeconds": 3600
}
]
}
AWS S3 und andere S3-kompatible Anbieter
Senden Sie dieses JSON an PutBucketCors, zum Beispiel mit aws s3api put-bucket-cors --bucket <name> --cors-configuration file://cors.json.
{
"CORSRules": [
{
"AllowedOrigins": [
"https://www.cargomarshal.com",
"https://cargomarshal.com",
"http://localhost:3000"
],
"AllowedMethods": ["GET", "HEAD", "PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]
}
Regel erzeugen und prüfen
Führen Sie pnpm storage:cors im Wurzelverzeichnis des Repositorys aus. Der Befehl liest apps/web/.env, oder apps/web/.env.test, wenn die erste Datei fehlt, und gibt für jeden konfigurierten Bucket beide JSON-Formen aus. Übergeben Sie ein --origin-Flag pro App-Origin. Ohne Flag verwendet der Befehl den Origin von NEXT_PUBLIC_APP_URL.
pnpm storage:cors --origin https://cargomarshal-git-my-branch.vercel.app
Um die echten Buckets zu testen, fügen Sie --check hinzu. Der Befehl sendet für jeden Origin einen lesenden Preflight (eine HTTP-OPTIONS-Anfrage, ohne Zugangsdaten und ohne Schreibzugriff). Er testet GET auf der öffentlichen URL, PUT auf dem Bucket für Bilder sowie PUT und GET auf dem privaten Bucket. Er gibt pro Probe eine PASS- oder FAIL-Zeile mit Begründung aus und endet mit Exit-Code 1, wenn eine Probe fehlschlägt.
pnpm storage:cors --check --origin https://cargomarshal-git-my-branch.vercel.app
Der Ladebericht und das Logo
Der Ladebericht fragt ein hochgeladenes PNG- oder JPEG-Logo zuerst beim Bild-Endpunkt der App an, /_next/image. Dieser Endpunkt lädt die Datei auf dem Server. Die Anfrage bleibt deshalb auf demselben Ursprung und hängt nicht von der CORS-Regel des Buckets ab.
In diesen Fällen lädt der Bericht das Logo stattdessen direkt von seiner URL. Ein Logo im öffentlichen Bucket braucht dann GET in der Regel oben:
- Das Logo ist ein SVG, oder die Organisation hat kein Logo und nutzt ihr erzeugtes DiceBear-Zeichen.
/_next/imageliefert kein SVG aus. - Der Bucket läuft unter einer privaten Adresse, zum Beispiel ein lokales MinIO auf
localhost. Next.js lädt keine Bilder von privaten Adressen, deshalb schlägt/_next/imagefehl. /_next/imageschlägt aus einem anderen Grund fehl, zum Beispiel weil der Host des Buckets in der Bild-Allowlist fehlt.
Schlägt auch die direkte Anfrage fehl, enthält der Bericht kein Logo. Behalten Sie GET in der Regel für beide Buckets. Ohne die PUT-Regel schlagen außerdem Uploads fehl, und Chat-Anhänge brauchen GET auf dem privaten Bucket.