
Bun.js + S3 + Sharp: eine Pipeline für Upload und Bildoptimierung
So entsteht eine sichere Bild-Pipeline mit Bun.js, presigned S3-URLs, Sharp, WebP-Varianten und serverseitiger Validierung.
Bun validiert die angeforderten Dateidaten und liefert eine kurzlebige presigned PUT-URL. Der Browser lädt direkt in S3-kompatiblen Storage. Ein Worker liest das Original, erstellt mit Sharp WebP- und Thumbnail-Varianten und veröffentlicht nur geprüfte Objekte.
Architektur ohne Proxy für Dateibytes
Bun ist die Control Plane, der Object Storage die Data Plane.
01
Upload vorbereiten
Der Client sendet Dateiname, MIME-Type und Größe. Die API prüft die Allowlist und liefert Key und presigned URL.
02
Direkt hochladen
Der Browser führt PUT nach S3 aus. Der Bun-Prozess hält die Datei nicht im Arbeitsspeicher.
03
Verarbeiten
Ein Worker liest das Original und Sharp erstellt Thumbnail und WebP-Vorschau.
04
Veröffentlichen
In der Datenbank werden nur geprüfte Keys, Dimensionen, MIME-Type und Status gespeichert.
Die Datei geht direkt in den Storage; Bun verwaltet Zugriff und Metadaten statt große Bytes zu proxyen.
Screenshot des Abschnitts architectureSchritt 1: SDK und Sharp installieren
Abhängigkeiten hinzufügen
bun add @aws-sdk/client-s3 @aws-sdk/s3-request-presigner sharpSharp enthält native Komponenten. Prüfe die optionalen Abhängigkeiten für die Docker-Zielplattform.
Bucket setzen
S3_REGION=eu-central-1
S3_BUCKET=media
S3_ENDPOINT=https://s3.example.com
S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...S3_ENDPOINT funktioniert auch mit R2 und MinIO. Der Secret Key darf nie ins Frontend.
Schritt 2: presigned PUT-URL ausstellen
Halte die URL kurzlebig, verwende einen zufälligen Object Key und binde sie an den erwarteten Content-Type. Prüfe die tatsächliche Objektgröße nach dem Upload.
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({ region: Bun.env.S3_REGION!, endpoint: Bun.env.S3_ENDPOINT || undefined, forcePathStyle: Boolean(Bun.env.S3_ENDPOINT) });
const allowed = new Set(["image/jpeg", "image/png", "image/webp"]);
export async function createUploadUrl(contentType: string) {
if (!allowed.has(contentType)) throw new Error("Unsupported image type");
const key = `originals/${crypto.randomUUID()}`;
const command = new PutObjectCommand({ Bucket: Bun.env.S3_BUCKET!, Key: key, ContentType: contentType, ServerSideEncryption: "AES256" });
return { key, url: await getSignedUrl(s3, command, { expiresIn: 300 }) };
}Upload vorbereiten und Status verfolgen
Setze eine Datei nicht schon bei der URL-Ausgabe auf ready. Lege zunächst einen Datensatz mit pending an und ändere ihn erst nach der Objektprüfung durch den Worker auf ready.
import { Elysia, t } from "elysia";
import { createUploadUrl } from "../storage";
export const uploadRoutes = new Elysia({ prefix: "/uploads" }).post("/prepare", async ({ body, set }) => {
const upload = await createUploadUrl(body.contentType);
// upload.key und userId mit status=pending speichern.
set.status = 201;
return { ...upload, status: "pending" };
}, { body: t.Object({ contentType: t.Union([t.Literal("image/jpeg"), t.Literal("image/png"), t.Literal("image/webp")]) }) });Sicherheit und Kostenkontrolle
Upload-Endpunkte brauchen Limits auf jeder Stufe.
Größe begrenzen
Payloads begrenzen und die tatsächliche Objektgröße nach PUT prüfen.
Keys serverseitig erzeugen
UUIDs und User-/Projekt-Namespace statt beliebiger Client-Keys verwenden.
Scannen oder moderieren
Bei öffentlichen Inhalten Antivirus oder Moderation vor ready einbauen.
Lifecycle-Regeln verwenden
Abgebrochene Uploads und temporäre Originals automatisch löschen.
Schwere Arbeit auslagern
Sharp in einem Worker ausführen, damit die Upload-API responsiv bleibt.
Die Bild-Pipeline testen
Teste das dekodierte Ergebnis, nicht nur den HTTP-Status. So werden Qualitätsregressionen und kaputte native Dependencies nach einem Docker-Update sichtbar.
import { expect, test } from "bun:test";
import sharp from "sharp";
import { makeVariants } from "./images";
test("erstellt ein begrenztes WebP-Thumbnail", async () => {
const input = await sharp({ create: { width: 1200, height: 800, channels: 3, background: "#f97316" } }).png().toBuffer();
const { thumbnail } = await makeVariants(input);
const meta = await sharp(thumbnail).metadata();
expect(meta.format).toBe("webp"); expect(meta.width).toBe(480); expect(meta.height).toBe(480);
});Starte bun test --coverage; verwende MinIO oder einen separaten Test-Bucket für Storage-Integrationstests.
FAQ
Ja, aber Sharp hat native Dependencies. Installiere sie für die Zielplattform und führe einen Smoke-Test im Production-Docker-Image aus.
Bei großen Dateien besser nicht. Verwende eine presigned URL und lade direkt in S3-kompatiblen Storage.
Fazit
Beschreiben Sie die Aufgabe — die ersten 15 Minuten der Beratung sind kostenlos.
Verwandte Artikel

AI Assistant Entwicklung Kosten 2026: RAG, Knowledge Base, Integrationen und Support
Praktischer Leitfaden zu Kosten fuer AI Assistants: RAG, Knowledge Base, Channels, Tool Use, Guardrails, Evaluations, Monitoring und Support.

KI fur Landingpage-Entwicklung: wo sie Launches beschleunigt und wo sie Conversion schadet
Eine praxisnahe Analyse zur Nutzung von KI fur Landingpages: v0, Webflow AI, Builder.io, Framer-ahnliche Builder, UX-Generierung, Copy, SEO, Personalisierung, A/B-Tests, Template-Risiken, Accessibility, Security und technischer Schuldenaufbau.

AI SEO / GEO im Jahr 2026: Ihre nächsten Kunden sind nicht Menschen — sondern Agents
Suche verschiebt sich von Klicks zu Antworten. Bots und AI-Agents crawlen, zitieren, empfehlen — und kaufen zunehmend. Erfahren Sie, was AI SEO / GEO bedeutet, warum klassisches SEO nicht mehr reicht und wie PAS7 Studio Marken im agentischen Web sichtbar macht.

Der leistungsstärkste Chip von Apple? M5 Pro und M5 Max brechen Rekorde
Eine Analyse zu Apple M5 Pro und M5 Max im März 2026. Wir zeigen, warum diese Chips als die stärksten professionellen Laptop-SoCs von Apple gelten können, wie sie sich gegen M4 Pro, M4 Max, M1 Pro, M1 Max schlagen und was der Vergleich mit aktuellen Intel- und AMD-Chips zeigt.
Professionelle Entwicklung für Ihr Geschäft
Wir erstellen moderne Web-Lösungen und Bots für Unternehmen. Erfahren Sie, wie wir Ihnen helfen können, Ihre Ziele zu erreichen.