Infrastructure

File Storage (S3/R2)

Dateien sicher in der Cloud speichern

Dateien auf deinem Server speichern funktioniert bis zum ersten Redeployment, dann sind sie weg. Cloud Storage wie S3 oder Cloudflare R2 ist die richtige Loesung: guenstig, skalierbar und persistent.

Pro-Tip — Der schnelle Weg
Nutze Cloudflare R2 statt AWS S3 wenn moeglich. R2 hat keine Egress-Kosten, das heisst du zahlst nichts fuer Downloads. Bei vielen Downloads spart dir das hunderte Euro im Monat.
Seite 1
1

AWS SDK installieren

Das AWS SDK funktioniert sowohl mit S3 als auch mit R2 weil R2 S3-kompatibel ist. Ein SDK fuer beide Dienste.

npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
2

Client konfigurieren

Erstelle einen S3-Client mit deinen Zugangsdaten. Fuer R2 aenderst du nur den Endpoint.

// lib/storage.ts
import { S3Client } from '@aws-sdk/client-s3';


export const s3 = new S3Client({
region: 'auto',
endpoint: process.env.S3_ENDPOINT!, // R2: https://<account>.r2.cloudflarestorage.com
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY!,
secretAccessKey: process.env.S3_SECRET_KEY!,
},
});
3

Presigned Upload URL generieren

Lade Dateien nie ueber deinen Server hoch. Generiere eine Presigned URL und der Client laedt direkt in den Storage hoch. Spart Server-Bandbreite.

import { PutObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';


export async function getUploadUrl(key: string, contentType: string) {
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: key,
ContentType: contentType,
});
return getSignedUrl(s3, command, { expiresIn: 3600 });
}
4

Upload im Frontend

Hole die Presigned URL von deiner API und lade die Datei direkt per PUT-Request in den Storage hoch.

async function uploadFile(file: File) {
// 1. Presigned URL holen
const res = await fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({ filename: file.name, type: file.type }),
});
const { uploadUrl, fileUrl } = await res.json();


// 2. Direkt zu S3/R2 uploaden
await fetch(uploadUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': file.type },
});


return fileUrl; // URL zum Anzeigen
}
Seite 2
Warum das funktioniert
  • Presigned URLs halten Dateien von deinem Server fern und sparen Bandbreite
  • S3-kompatibel bedeutet du kannst jederzeit den Anbieter wechseln
  • Cloud Storage ueberlebt Redeployments im Gegensatz zu lokalem Dateisystem
  • R2 ohne Egress-Kosten macht Datei-Download effektiv kostenlos
Tipps
  • Generiere eindeutige Dateinamen mit crypto.randomUUID() um Konflikte zu vermeiden
  • Setze eine maximale Dateigroesse in der Presigned URL um Missbrauch zu verhindern
  • Nutze einen CDN-Subdomain fuer Downloads damit Bilder schnell weltweit geladen werden
  • Loesche nicht mehr benoetigte Dateien automatisch mit Lifecycle Rules
Seite 3
Bereit für den nächsten Schritt?

KIWorld VibeCoding Masterclass

Du willst nicht nur einzelne Tools einrichten, sondern wirklich lernen wie du mit KI komplette Apps, Websites und SaaS-Produkte baust? Über 700 Videos — von Anfänger bis Fortgeschritten — in jedem Bereich. Von der Idee bis zum fertigen Produkt, ohne eine Zeile Code selbst zu schreiben.

Jetzt Masterclass ansehen