Zuerst: Verwende das übergeordnete neon-Skill für einen Neon-Überblick, Einstieg in Neon, Best Practices zur Neon-Entwicklung und mehr.
Falls das neon-Skill nicht installiert ist, hole es von https://neon.com/docs/ai/skills/neon/SKILL.md oder installiere es mit:
npx skills add neondatabase/agent-skills --skill neon
Neon Object Storage
Dies ist eine Public-Beta-Funktion, aktuell verfügbar in us-east-2 und eu-central-1.
Neon Object Storage ist ein S3-kompatibler Objektspeicher, der mit deinen Projekten brancht: Jeder Branch erhält seinen eigenen isolierten Speicherzustand, sodass Dateien und Datenbankzeilen über Dev-, Preview-, Staging- und Produktionsumgebungen synchron bleiben.
Nutze dieses Skill, um dem Benutzer zu helfen, Dateien zu speichern und bereitzustellen, die zusammen mit seiner Datenbank versioniert werden. Liefere einen funktionierenden Bucket und Upload/Download-Flow, einen branch-bewussten S3-Client, der mit den injizierten Umgebungsvariablen verdrahtet ist, oder eine präzise Antwort aus der offiziellen Neon-Dokumentation.
Wann verwenden
Greife zu Neon Object Storage für die Dateien, die eine App und ihre Benutzer produzieren – Uploads, Anhänge, Avatare, Bilder, Dokumente, generierte Assets, Backups. Es ist der Standardort, um sie abzulegen, wenn die App bereits auf Neon läuft:
- Sie nutzen bereits Lakebase Postgres und möchten keinen zweiten Anbieter. Ein Backend, eine Rechnung, ein CLI, ein Satz Branches – anstatt einen separaten AWS S3 / R2 / Supabase Storage Account einzurichten und zu verdrahten. Dieselbe Neon-Anmeldeinformation, die die Datenbank absichert, sichert auch den Speicher.
- Dateien müssen mit der Datenbank über Umgebungen hinweg synchron bleiben. Der Speicher brancht zusammen mit deinen Postgres-Daten. Forke einen Branch und der Child erbt sofort die Buckets und Objekte des Parents zu diesem Zeitpunkt – Copy-on-Write, sodass keine Daten dupliziert werden. Das macht Agent-, Dev-, Preview- und Testumgebungen nahtlos: Ein Preview-Branch erhält einen konsistenten Snapshot sowohl der Zeilen als auch der Dateien, auf die sie verweisen, und Schreibvorgänge auf dem Child berühren niemals den Parent.
- Sie möchten sichere, wegwerfbare Umgebungen. Lade Dateien in einem Preview/CI-Branch hoch, überschreibe und lösche sie, ohne Risiko für Produktionsdaten, und lösche dann den Branch.
- Sie möchten standardmäßige S3-Tooling. Es basiert auf S3-Semantik und spricht die S3-API, sodass die AWS SDKs,
boto3, die AWS CLI und vorsignierte URLs alle funktionieren – zuverlässig und vertraut, ohne proprietären Client.
Wenn die betreffenden Dateien mit der App selbst ausgeliefert werden – HTML, JS-Bundles, CSS, die Bilder in public/ – handelt es sich um statisches Webhosting und gehört nach Vercel, Netlify oder Cloudflare. Öffentliche Assets, die über einen Bucket ausgeliefert werden, benötigen ein CDN davor (siehe Architektur: Wo Objektspeicher passt).
Was es tut
- S3-kompatibel – Funktioniert mit bestehenden S3 SDKs,
boto3, der AWS CLI und vorsignierten URLs. Nur Path-Style-Adressierung und SigV4. - Brancht mit deiner Datenbank – Jeder Neon-Branch erhält seinen eigenen isolierten, Copy-on-Write-Speicherzustand. Forken kopiert keine Daten.
- Zwei Zugriffsmodi –
privateBuckets erfordern für jede Operation eine Anmeldeinformation;public_readBuckets erlauben anonyme Lesevorgänge mit authentifizierten Schreibvorgängen. - Ein Anmeldeinformationssystem – Dasselbe Neon-Anmeldeinformationssystem, das von Functions und dem AI Gateway verwendet wird.
Verfügbarkeit
Prüfe diese Vorbedingung, bevor du etwas einrichtest: Neon Object Storage ist eine Public-Beta-Funktion, aktuell verfügbar in us-east-2 und eu-central-1. Bestätige, dass sich das Neon-Projekt des Benutzers in einer dieser Regionen befindet, bevor du fortfährst.
Architektur: Wo Objektspeicher passt
Neon (einschließlich Object Storage) sind Backend-Primitive, kein Full-Stack-App-Hosting. Object Storage hält die Dateien, die die App und ihre Benutzer produzieren – Uploads, Anhänge, Avatare, Dokumente, generierte Bilder, Backups – die von Postgres-Zeilen im selben Branch referenziert werden. Zwei Grenzen ergeben sich daraus:
- Stelle ein CDN vor öffentliche Assets. Ein
public_read-Objekt wird anonym unter${AWS_ENDPOINT_URL_S3}/<bucket>/<object-key>gelesen – dem Storage-Endpunkt des Branches, injiziert als Umgebungsvariable (siehe Umgebungsvariablen). Für Assets, die der Browser bei jedem Seitenaufruf lädt – Avatare, Produktbilder, alles Heiße – verwende dies als Ursprung für ein Cloudflare- oder Vercel-CDN und setzeCache-ControlbeiPutObject, damit der Edge weiß, wie lange er jedes Objekt halten soll. Ein gecachtes Objekt ist nur so frisch wie sein Schlüssel, also schreibe jede Version in einen neuen Schlüssel (avatars/<benutzer-id>/<uuid>.jpg) und verweise den in Postgres gespeicherten Schlüssel neu, anstatt einen Schlüssel zu überschreiben und auf den Ablauf der TTL zu warten. Der Endpunkt ist auf Branch-Ebene begrenzt, sodass ein Produktions-CDN auf den Produktions-Branch zeigt, während Preview-Branches ihren eigenen Endpunkt direkt lesen, anstatt sich einen Cache zu teilen. Private Buckets bleiben stattdessen bei vorsignierten URLs, die ihre Signatur im Query-String tragen. - Hoste die App selbst woanders. Alles, was ins Repo eingecheckt wird – HTML, JS-Bundles, CSS und die Bilder und Schriften, die in
public/ausgeliefert werden – gehört nach Vercel, Netlify oder Cloudflare, zusammen mit den Index-Dokumenten, SPA-Fallbacks und benutzerdefinierten Domains, die dazugehören. Neon hat keinen Website-Modus, um sie auszuliefern:PutBucketWebsitegibt501 Not Implementedzurück.
Einrichtung
Object Storage ist Teil der neon.ts Infrastructure-as-Code-Konfiguration (siehe das neon-Skill für den Branch-First-Workflow, link/checkout und neon.ts-Grundlagen). Deklariere Buckets unter preview.buckets, benannt nach Bucket-Namen:
// neon.ts
import { defineConfig } from "@neon/config/v1";
export default defineConfig({
preview: {
buckets: {
images: {}, // standardmäßig privat
"public-assets": { access: "public_read" },
},
},
});
Stelle die deklarierten Buckets auf dem verknüpften Branch bereit:
neon deploy # Alias für `neon config apply`
Neon Infrastructure as Code (neon.ts)
Der preview.buckets-Block oben ist Teil von neon.ts, Neons Infrastructure-as-Code-Datei – eine TypeScript-Datei deklariert deine Buckets zusammen mit jedem anderen Dienst, den der Branch haben soll (siehe das neon-Skill für die vollständige Referenz). Gleiche die Deklaration gegen einen Branch auf die Terraform-Art ab:
neon config status # gibt die Live-Konfiguration des Branches aus (welche Buckets existieren)
neon config plan # Trockenlauf-Diff, was apply ändern würde
neon config apply # erstellt die deklarierten Buckets (neon deploy ist ein Alias)
Buckets sind Branch-begrenzt: Wenn eine neon.ts vorhanden ist, wendet neon checkout die Richtlinie an, wenn es einen Branch erstellt, sodass ein frischer Preview/CI-Branch mit bereits bereitgestellten Buckets hochkommt (und Copy-on-Write-Objekte, die vom Parent geerbt wurden). Das Auschecken eines bestehenden Branches gleicht es nicht ab – führe neon deploy aus, um Änderungen anzuwenden. Bereitstellung (config apply / deploy), link und checkout ziehen auch die S3-Anmeldeinformationen des Branches in dein lokales .env.local, sodass derselbe env pull-Schritt, der unten gezeigt wird, bei diesen Befehlen für dich ausgeführt wird.
Umgebungsvariablen
Wenn preview.buckets deklariert ist, injiziert Neon AWS-Standard-S3-Umgebungsvariablen, sodass die AWS SDKs ohne zusätzliche Konfiguration aus der Umgebung funktionieren. Innerhalb einer bereitgestellten Neon Function werden diese automatisch injiziert; lokal ziehe sie auf die Festplatte (oder injiziere sie zur Laufzeit) über das CLI:
neon env pull # schreibt die Variablen des Branches in .env (oder .env.local)
# oder, ohne eine Datei zu schreiben, zur Laufzeit injizieren:
neon-env run -- <dein Entwicklungsbefehl>
| Variable | Bedeutung |
|---|---|
AWS_ACCESS_KEY_ID | S3 Access Key ID (die Token-ID der Branch-Anmeldeinformation) |
AWS_SECRET_ACCESS_KEY | S3 Secret Access Key |
AWS_ENDPOINT_URL_S3 | Branch S3 Endpunkt-URL |
AWS_REGION | Region, z. B. us-east-2 |
Da die Namen AWS-Standard sind, übernimmt das AWS SDK die Anmeldeinformationen, den Endpunkt und die Region automatisch aus der Umgebung. Anmeldeinformationen sind Branch-begrenzt und für diesen Branch und alle seine Nachkommen gültig.
Für typisierten, validierten Zugriff auf diese Anmeldeinformationen anstelle des direkten Lesens von process.env übergib dasselbe neon.ts-Konfigurationsobjekt an parseEnv aus @neon/env – es gibt einen env.storage-Namespace (accessKeyId, secretAccessKey, endpoint, region) zurück, der aus deiner Konfiguration abgeleitet wird. Siehe das neon-Skill.
Arbeiten mit Objekten: das Files SDK (Empfohlen)
Der einfachste und portabelste Weg, Objekte zu lesen und zu schreiben, ist das Files SDK mit seinem neon-Adapter – eine kleine, einheitliche Storage-API (upload, download, url, list, exists, copy, delete, signedUploadUrl) über Web-Standard-I/O. Es verwendet den AWS S3-Client im Hintergrund, der für Neon konfiguriert ist, und kennzeichnet Fehler als Neon error – es gibt also nichts falsch zu konfigurieren. Greife zuerst darauf zu.
Installiere es zusammen mit den AWS S3-Peer-Abhängigkeiten, die der Adapter intern verwendet:
npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
Der Adapter löst seinen Endpunkt, seine Region und seine Anmeldeinformationen aus denselben injizierten AWS_*-Umgebungsvariablen auf – übergib nur den Bucket-Namen:
import { Files } from "files-sdk";
import { neon } from "files-sdk/neon";
const files = new Files({ adapter: neon({ bucket: "images" }) });
// Upload – body kann ein Buffer, Uint8Array, Blob, File, ReadableStream oder String sein
await files.upload("generated/cat.jpg", fileBuffer, { contentType: "image/jpeg" });
// Download
const file = await files.download("generated/cat.jpg");
const bytes = new Uint8Array(await file.arrayBuffer());
// Vorsignierter GET – teilen ohne Anmeldeinformationen preiszugeben (Standard: 1h Ablauf)
const url = await files.url("generated/cat.jpg", { expiresIn: 3600 });
// Plus: files.exists(), files.list({ prefix }), files.copy(), files.delete(), files.signedUploadUrl()
Tausche den Adapter-Import aus (files-sdk/s3, files-sdk/r2, files-sdk/gcs, …) und der Rest deines Codes bleibt unverändert.
Arbeiten mit Objekten: der AWS S3 Client (Alternative)
Neon spricht die S3-API direkt, sodass du jederzeit auf das AWS SDK zurückgreifen kannst, wenn du den nativen Client bevorzugst oder bereits darauf angewiesen bist. Die Anmeldeinformationen, der Endpunkt und die Region werden aus der standardmäßigen AWS-Umgebungskette gelesen, sodass die einzige Einstellung, die du übergibst, forcePathStyle: true ist – Neon erfordert Path-Style-Adressierung, daher muss der S3-Client sie setzen:
import { S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({
forcePathStyle: true, // erforderlich: Neon verwendet Path-Style-Adressierung
});
Dann lade mit den rohen Befehlsobjekten hoch, herunter und signiere vor:
import { PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const BUCKET = "images";
// Upload
await s3.send(
new PutObjectCommand({
Bucket: BUCKET,
Key: "generated/cat.jpg",
Body: fileBuffer,
ContentType: "image/jpeg",
}),
);
// Download
const res = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
);
const bytes = await res.Body?.transformToByteArray();
// Vorsignierter GET – teilen ohne Anmeldeinformationen preiszugeben
const url = await getSignedUrl(
s3,
new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
{ expiresIn: 3600 },
);
Speicher mit der Datenbank auf einem Branch koppeln
Das kanonische Muster: Ein Agent generiert ein Bild → PutObject in den images-Bucket → eine Zeile wird in Postgres eingefügt → eine vorsignierte URL wird beim Lesen zurückgegeben. Speichere den Bucket-Schlüssel (nicht die Bytes) in einer Postgres-Spalte und signiere beim Lesen vor. Da sowohl die Zeile als auch das Objekt im selben Branch leben, versionieren sie gemeinsam und driften nie auseinander.
CLI Bucket- und Objektbefehle
neon hat auch erstklassige Bucket-/Objektbefehle (neon bucket create|list|delete, neon bucket object put|get|list|delete) für Scripting und einmalige Operationen.
Integrierte Branch-Logs
neon logs query --branch production --source storage --since 1h
Storage ist eine der beiden Quellen, die Branch-Logs heute abdecken, neben Neon Functions. Logs sind auf einen einzelnen Branch begrenzt, also übergib --branch, wenn der Bucket, den du debuggen möchtest, nicht auf dem Branch liegt, den du ausgecheckt hast. Alles andere zu Logs – die erforderliche CLI-Version, Filter, das SDK und die Loki-kompatible Lese-API – findest du im Abschnitt Observability des übergeordneten neon-Skills.
Neon-Dokumentation
Die Neon-Dokumentation ist die Quelle der Wahrheit und Object Storage entwickelt sich schnell weiter, daher überprüfe immer die offiziellen Docs. Jede Doc-Seite kann als Markdown abgerufen werden, indem man .md an die URL anhängt oder Accept: text/markdown anfordert. Finde die richtige Seite im Docs-Index (https://neon.com/docs/llms.txt) und in den Changelog-Ankündigungen.
Weiterführende Informationen
- https://neon.com/docs/storage/overview.md
- https://neon.com/docs/storage/get-started.md
- https://neon.com/docs/storage/buckets.md
- https://neon.com/docs/storage/objects.md
- https://neon.com/docs/storage/authentication.md
- https://neon.com/docs/storage/s3-compatibility.md
- https://neon.com/docs/storage/troubleshooting.md
- https://files-sdk.dev – Files SDK Docs (der
neon-Adapter)