TechnologieProgrammierung

Ein MinIO-Server als gemeinsamer S3-Speicher für viele Anwendungen

netcomputing.de Redaktion26. August 202610 Min. Lesezeit

Zusammenfassung

Wer für jede Anwendung Dateien anders speichert oder einzelne Cloud-Speicher-Abos bezahlt, kann das auf einem selbstgehosteten MinIO-Server bündeln. MinIO bietet dieselbe S3-Schnittstelle wie Amazon S3, jede Anwendung greift per S3-SDK zu und sieht nur ihren eigenen, durch Access Key und Policy abgesicherten Bucket. Ein Docker-Server mit persistentem Volume und Erasure-Codierung über mehrere Laufwerke schützt die Daten vor Ausfällen. Die freie MinIO-Version wird seit ihrer Archivierung im April 2026 allerdings nicht mehr weiterentwickelt.

Ein Unternehmen, das zehn oder zwanzig eigene Anwendungen betreibt, sammelt dabei zwangsläufig auch zehn oder zwanzig Arten von Dateiablage an. Der PDF-Generator einer Buchhaltungsanwendung schreibt Rechnungen auf die lokale Festplatte des Servers. Ein Kundenportal legt hochgeladene Fotos in einem Ordner ab, den niemand sichert. Ein nächtlicher Batch-Job kopiert Exportdateien in ein Verzeichnis, das bei der nächsten Serverneuinstallation verschwindet. Jede Anwendung löst dasselbe Problem auf ihre eigene Art, und keine der Lösungen kennt Redundanz, einen einheitlichen Zugriffsweg oder eine gemeinsame Berechtigungsstruktur.

MinIO schließt diese Lücke, indem es einen einzigen Objektspeicher-Server bereitstellt, den alle Anwendungen gemeinsam nutzen. Ein Objektspeicher verwaltet Dateien als abgeschlossene Objekte mit Metadaten, statt sie wie ein klassisches Dateisystem in einer Ordnerhierarchie abzulegen, und MinIO spricht dabei dieselbe Schnittstelle wie Amazon S3, die von Amazon Web Services entwickelte und inzwischen von den meisten Cloud-Anbietern nachgebaute Programmierschnittstelle für Objektspeicher (Simple Storage Service). Jede Anwendung bekommt einen eigenen Bucket, den Container für ihre Objekte innerhalb des gemeinsamen Servers, und einen eigenen Zugriffsschlüssel, der ausschließlich auf diesen einen Bucket zugreifen darf. Weil die Schnittstelle mit echtem S3 identisch ist, lässt sich jede Anwendung, die bereits mit einem S3-kompatiblen SDK entwickelt wurde, ohne Codeänderung auf den selbstgehosteten Server umstellen. Nur die Verbindungsadresse ändert sich.

Systemvoraussetzungen

Eine Installation kommt mit wenigen Bausteinen aus. Die folgende Tabelle listet sie mit den Angaben aus der aktuellen Projektdokumentation und der Docker-Distribution auf. Ein Hinweis vorab: Das MinIO-Projekt hat sein GitHub-Repository am 25. April 2026 als archiviert markiert, nachdem der Hersteller die freie Community Edition bereits im Dezember 2025 in einen Wartungsmodus versetzt und die Weiterentwicklung auf sein kommerzielles Produkt AIStor verlagert hatte. Das zuletzt veröffentlichte Docker-Image mit dem Stand vom 7. September 2025 funktioniert unverändert weiter, bekommt aber keine garantierten Sicherheitsupdates mehr. Wer MinIO neu aufsetzt, sollte diesen Stand kennen, bevor er die Entscheidung trifft.

KomponenteVersion oder AnforderungZweck
MinIO-Server (Docker-Image)RELEASE.2025-09-07T16-13-09Z (letztes veröffentlichtes Image der freien Community Edition, seither ohne Nachfolger)S3-kompatibler Objektspeicher-Server
Docker Engine mit Compose-PluginAktuelle stabile Docker-VersionBetrieb und Orchestrierung des Containers
Persistentes VolumeEigenes Verzeichnis oder benanntes Docker-Volume, gemountet auf /data im ContainerSpeichert Objektdaten und Metadaten dauerhaft über Neustarts hinweg
mc-ClientKommandozeilenwerkzeug des MinIO-ProjektsVerwaltung von Buckets, Nutzern, Zugriffsschlüsseln und Policies
S3-kompatibles SDK in jeder AnwendungZum Beispiel @aws-sdk/client-s3 (AWS SDK for JavaScript v3)Verbindet die jeweilige Anwendung mit dem Objektspeicher
Mehrere Laufwerke für Erasure-CodierungTechnisches Minimum 2 Laufwerke je Erasure-Set, für den produktiven Einsatz verlangt das Projekt eine Parität von EC:3 oder höher, was mindestens 6 Laufwerke voraussetztÜbersteht den Ausfall einzelner Laufwerke ohne Datenverlust

Der Docker-Tag latest zeigt derzeit noch auf dieses letzte Release, verändert sich aber nicht mehr von selbst nach vorn. Trotzdem sollte jede Installation den konkreten Tag aus der Tabelle referenzieren statt latest, damit ein Neustart des Containers nicht unbemerkt ein anderes Abbild zieht.

Systemarchitektur

flowchart TD
    A[Anwendung 1 fuer PDF Erzeugung] --> SDK1[AWS SDK v3 Client mit eigenem Access Key]
    B[Anwendung 2 fuer Foto Uploads] --> SDK2[AWS SDK v3 Client mit eigenem Access Key]
    C[Anwendung 3 fuer taegliche Backups] --> SDK3[AWS SDK v3 Client mit eigenem Access Key]
    SDK1 --> MinIO[Ein gemeinsamer MinIO Server]
    SDK2 --> MinIO
    SDK3 --> MinIO
    MinIO --> Bucket1[Bucket pdf-generator]
    MinIO --> Bucket2[Bucket foto-upload]
    MinIO --> Bucket3[Bucket nachtlauf-backup]
    Bucket1 --> Disks[Erasure codierte Laufwerke]
    Bucket2 --> Disks
    Bucket3 --> Disks

Mehrere getrennte Anwendungen laufen dabei gegen genau einen MinIO-Server, nicht gegen mehrere eigene Instanzen. Die Trennung passiert vollständig auf Ebene der Zugriffsschlüssel, nicht auf Ebene getrennter Server. Jede Anwendung erhält beim Einrichten einen eigenen Access Key und Secret Key, das Zugangsschlüsselpaar, mit dem sie sich gegenüber dem Server authentifiziert, und dieser Schlüssel ist über eine Policy, eine im JSON-Format hinterlegte Zugriffsregel, auf genau einen Bucket beschränkt. Beim Hochladen sendet die Anwendung eine PUT-Anfrage an den S3-Endpoint des Servers, MinIO prüft die mitgelieferten Zugangsdaten gegen die hinterlegte Policy und schreibt das Objekt erst danach in den zugewiesenen Bucket. Beim Lesen läuft derselbe Weg umgekehrt: Die Anwendung fragt ein Objekt über seinen Schlüsselnamen ab, und MinIO liefert es aus, sofern die Policy des verwendeten Zugriffsschlüssels den lesenden Zugriff auf diesen Bucket erlaubt. Auf der Speicherebene darunter verteilt MinIO die Daten über mehrere Laufwerke mit Erasure-Codierung, einem mathematischen Verfahren, das jedes Objekt in Datenfragmente und zusätzliche Prüf-Fragmente zerlegt. Fällt eines der Laufwerke aus, rekonstruiert MinIO das fehlende Fragment aus den verbliebenen, ohne dass eine der drei Anwendungen davon etwas merkt.

Schritt-für-Schritt-Umsetzung

MinIO per Docker Compose mit persistentem Speicher aufsetzen

Der Server selbst startet als einzelner Container. Die folgende Compose-Datei bindet ein benanntes Docker-Volume ein, das die Objektdaten unabhängig vom Lebenszyklus des Containers speichert, setzt die beiden Zugangsdaten-Variablen für den root-Benutzer und öffnet sowohl den API-Port für S3-Anfragen als auch den Port der Weboberfläche.

version: "3.8"
services:
  minio:
    image: minio/minio:RELEASE.2025-09-07T16-13-09Z
    container_name: minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: firma-admin
      MINIO_ROOT_PASSWORD: ein-mindestens-8-zeichen-langes-passwort
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio-data:/data
    restart: unless-stopped

volumes:
  minio-data:

Port 9000 nimmt alle S3-kompatiblen API-Anfragen entgegen, also genau die Anfragen, die später auch das SDK der jeweiligen Anwendung stellt. Port 9001 liefert ausschließlich die Weboberfläche zur manuellen Verwaltung von Buckets und Nutzern und gehört in einem produktiven Aufbau hinter einen eigenen Zugriffsschutz, etwa einen Reverse Proxy mit Basisauthentifizierung. MINIO_ROOT_USER und MINIO_ROOT_PASSWORD legen dabei nur den root-Benutzer an, der die gesamte Instanz verwaltet. Für die einzelnen Anwendungen entstehen im nächsten Schritt eigene, eingeschränkte Zugriffsschlüssel, damit keine Anwendung mit den root-Zugangsdaten arbeitet.

Bucket und Access Key je Anwendung anlegen

Mit dem laufenden Server verbindet sich der mc-Client, das Kommandozeilenwerkzeug von MinIO für Verwaltungsaufgaben, über einen einmalig gespeicherten Alias.

mc alias set firma-minio http://localhost:9000 firma-admin ein-mindestens-8-zeichen-langes-passwort --api s3v4

mc mb firma-minio/pdf-generator
mc mb firma-minio/foto-upload
mc mb firma-minio/nachtlauf-backup

Jeder mc mb-Befehl legt einen eigenen Bucket an, hier je einen für den Rechnungs-PDF-Generator, den Foto-Upload des Kundenportals und den nächtlichen Backup-Job. Damit keine Anwendung auf den Bucket einer anderen zugreifen kann, bekommt jeder Bucket eine eigene Policy, ein im selben Schema wie eine AWS-IAM-Policy geschriebenes JSON-Dokument, das Aktionen und Ressourcen explizit auflistet.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::pdf-generator",
        "arn:aws:s3:::pdf-generator/*"
      ]
    }
  ]
}

Die beiden Einträge im Feld Resource sind nötig, weil der Bucket selbst und die Objekte darin als getrennte Ressourcen gelten: Der erste Eintrag erlaubt das Auflisten des Bucket-Inhalts, der zweite den Zugriff auf die einzelnen Dateien darin. Ein eigener MinIO-Benutzer je Anwendung bekommt diese Policy zugewiesen und erhält damit einen Zugriffsschlüssel, der ausschließlich innerhalb von pdf-generator lesen und schreiben darf.

mc admin policy create firma-minio pdf-generator-policy pdf-generator-policy.json
mc admin user add firma-minio pdf-generator-user ein-eigenes-langes-passwort
mc admin policy attach firma-minio pdf-generator-policy --user=pdf-generator-user

Derselbe Dreischritt, ein eigener Bucket, eine eigene Policy-Datei, ein eigener Benutzer, wiederholt sich für jede weitere Anwendung. Der root-Zugriffsschlüssel aus der Compose-Datei bleibt dabei ausschließlich für Verwaltungsaufgaben reserviert und taucht in keiner Anwendungskonfiguration mehr auf.

Anwendung per AWS SDK an MinIO anbinden

Eine Anwendung, die bereits mit dem AWS SDK for JavaScript v3 gegen echtes S3 entwickelt wurde, braucht für die Umstellung auf den selbstgehosteten Server nur zwei zusätzliche Angaben in der Client-Konfiguration.

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "http://minio.internes-netz.example:9000",
  region: "us-east-1",
  forcePathStyle: true,
  credentials: {
    accessKeyId: process.env.PDF_GENERATOR_ACCESS_KEY,
    secretAccessKey: process.env.PDF_GENERATOR_SECRET_KEY,
  },
});

await s3.send(
  new PutObjectCommand({
    Bucket: "pdf-generator",
    Key: "rechnungen/2026-08/re-4471.pdf",
    Body: pdfBuffer,
    ContentType: "application/pdf",
  })
);

Die Angabe endpoint lenkt den Client vom Standard-Endpunkt von AWS auf die eigene MinIO-Adresse um. forcePathStyle ist die zweite, leicht zu übersehende Einstellung: Sie sorgt dafür, dass der Bucket-Name als Teil des URL-Pfads übertragen wird statt als Subdomain vor dem Hostnamen, das AWS SDK-intern virtual-hosted-style-Adressierung nennt. In der Amazon-Cloud lösen DNS-Einträge jede Subdomain automatisch auf den passenden Bucket auf, ein selbstgehosteter Server wie MinIO kennt solche Einträge nicht. region muss ebenfalls gesetzt sein, auch wenn MinIO Regionen nicht im AWS-Sinn kennt, weil das SDK ohne einen Regionswert die Anfrage gar nicht erst signiert.

Häufige Fehlerquellen

  • forcePathStyle fehlt in der Client-Konfiguration. Ohne diese Einstellung baut das SDK die Adresse im virtual-hosted-Format und versucht, den Bucket-Namen als Subdomain aufzulösen, etwa pdf-generator.minio.internes-netz.example. Diese Subdomain existiert im internen DNS nicht, und die Anfrage scheitert bereits bei der Namensauflösung mit einem Fehler wie getaddrinfo ENOTFOUND, lange bevor MinIO die Zugangsdaten überhaupt prüfen kann. Fix: forcePathStyle: true immer setzen, sobald der Endpoint nicht auf eine echte AWS-Adresse zeigt.
  • Kein Wert für region gesetzt. Das SDK benötigt einen Regionswert, um die Signatur jeder Anfrage zu berechnen, auch wenn MinIO selbst keine Regionen im AWS-Sinn führt. Fix: einen beliebigen gültigen Regionswert wie us-east-1 fest eintragen.
  • Anwendung nutzt den root-Zugriffsschlüssel statt eines eigenen Benutzers. Ein root-Schlüssel in der Konfiguration einer einzelnen Anwendung kann auf jeden Bucket der gesamten Instanz zugreifen. Ein Fehler oder ein kompromittiertes Deployment dieser einen Anwendung setzt dann die Daten aller anderen Anwendungen aufs Spiel. Fix: für jede Anwendung einen eigenen Benutzer mit einer auf genau einen Bucket beschränkten Policy anlegen und root-Zugangsdaten nur für Verwaltungsaufgaben verwenden.
  • Kein persistentes Volume gemountet. Startet der Container ohne das Volume aus der Compose-Datei, schreibt MinIO alle Objekte in den beschreibbaren Layer des Containers selbst. Ein Neustart oder ein Update des Images löscht diesen Layer und mit ihm sämtliche gespeicherten Dateien aller angeschlossenen Anwendungen. Fix: Das Volume vor dem ersten Start anlegen und in jeder Compose-Definition auf denselben Pfad verweisen.
  • Bucket-Name mit Großbuchstaben oder uneinheitlicher Schreibweise angelegt. MinIO folgt denselben Benennungsregeln wie S3 und akzeptiert in Bucket-Namen keine Großbuchstaben. Ein Bucket-Name wie PDF-Generator wird beim Anlegen abgelehnt, und eine Anwendung, die ihn dennoch fest in der Konfiguration erwartet, findet ihren Bucket nicht wieder. Fix: Bucket-Namen durchgehend klein schreiben und eine feste Namenskonvention je Anwendung dokumentieren.

Häufig gestellte Fragen

Was ist MinIO und wofür wird es eingesetzt?

MinIO ist ein Objektspeicher-Server, der dieselbe Programmierschnittstelle wie Amazon S3 bereitstellt und sich auf eigener Hardware oder in einem eigenen Rechenzentrum betreiben lässt. Unternehmen setzen MinIO ein, um Datei-Uploads, generierte PDFs, Bilder oder Backups mehrerer Anwendungen an einer zentralen Stelle zu speichern, statt für jede Anwendung einzeln einen Cloud-Speicher-Vertrag abzuschließen oder Dateien unkoordiniert auf lokalen Festplatten abzulegen. Jede Anwendung greift dabei über ein S3-kompatibles SDK zu, genau wie sie es bei echtem AWS S3 täte, nur mit einer eigenen Serveradresse.

Wie trennt MinIO die Daten mehrerer Anwendungen auf einem gemeinsamen Server?

MinIO trennt die Daten mehrerer Anwendungen über Buckets und Zugriffsschlüssel, nicht über getrennte Serverinstanzen. Jede Anwendung bekommt einen eigenen Bucket, den Container für ihre Objekte, sowie einen eigenen Access Key und Secret Key, die über eine im JSON-Format hinterlegte Policy ausschließlich auf diesen einen Bucket beschränkt sind. Eine Anwendung mit einem solchen eingeschränkten Zugriffsschlüssel kann weder die Buckets anderer Anwendungen sehen noch auf sie zugreifen, selbst wenn alle Buckets auf demselben MinIO-Server liegen.

Ab wie vielen Laufwerken schützt die Erasure-Codierung von MinIO vor einem Festplattenausfall?

Die Erasure-Codierung von MinIO greift technisch bereits ab zwei Laufwerken, dem dokumentierten Minimum für ein sogenanntes Erasure-Set, innerhalb dessen MinIO jedes Objekt in Datenfragmente und zusätzliche Prüf-Fragmente aufteilt. Für einen produktiven Einsatz mit echtem Ausfallschutz verlangt das Projekt laut eigener Dokumentation aber eine Parität von mindestens EC:3, was sechs Laufwerke je Erasure-Set voraussetzt, drei für die eigentlichen Daten und drei für Prüf-Fragmente. Mit weniger als drei Prüf-Fragmenten bleibt bei einem laufenden Laufwerkstausch oder einer Wartung oft nur noch eine einzige Reserve übrig, was für einen produktiven Betrieb nicht ausreicht. Je mehr Prüf-Fragmente eine Konfiguration vorsieht, desto mehr gleichzeitige Laufwerksausfälle übersteht sie, allerdings auf Kosten der nutzbaren Speicherkapazität.

Wird die freie MinIO Community Edition nach der Archivierung des Projekts noch weiterentwickelt?

Die freie MinIO Community Edition wird nach der Archivierung ihres GitHub-Repositorys am 25. April 2026 nicht mehr aktiv weiterentwickelt. Der Hersteller hatte das Projekt bereits im Dezember 2025 in einen Wartungsmodus versetzt und veröffentlicht seither keine neuen Docker-Images oder garantierten Sicherheitsupdates mehr für die freie Version, deren zuletzt erschienenes Image den Stand vom 7. September 2025 trägt. MinIO Inc. positioniert stattdessen sein kommerzielles Produkt AIStor als Nachfolger. Eine bestehende Installation läuft davon technisch unverändert weiter, wer aber auf garantierte künftige Sicherheitsupdates angewiesen ist, sollte diesen Umstand in die Entscheidung für oder gegen einen Neuaufbau auf Basis der freien Version einbeziehen.

Quellen

  1. MinIO GitHub-Repository (Archivierungshinweis vom 25. April 2026 und Verweis auf AIStor), MinIO Inc. / GitHub, abgerufen am 2026-08-26
  2. MinIO Docker Quickstart Guide (API- und Konsolen-Port, Root-Umgebungsvariablen, persistentes Volume), MinIO-Projekt, abgerufen am 2026-08-26
  3. Tag-Übersicht für minio/minio auf Docker Hub (letztes veröffentlichtes Image, Archivierungsstatus), Docker Hub, abgerufen am 2026-08-26
  4. MinIO AIStor Dokumentation zur Erasure-Codierung (Erasure-Set, Mindestanzahl Laufwerke, Parität), MinIO Inc., abgerufen am 2026-08-26
  5. MinIO AIStor IAM-Zugriffsdokumentation (AWS-IAM-kompatibles Policy-JSON-Schema), MinIO Inc., abgerufen am 2026-08-26
  6. MinIO Multi-User-Admin-Anleitung (Befehle mc admin user add und mc admin policy attach), MinIO-Projekt, abgerufen am 2026-08-26
  7. Anleitung zur Anbindung von Node.js an MinIO über das AWS SDK v3 (forcePathStyle), Northflank, abgerufen am 2026-08-26
  8. AWS SDK for JavaScript v3 Migrationsleitfaden für Amazon S3, Amazon Web Services, abgerufen am 2026-08-26

Der Content wurde mit Hilfe von KI erstellt, vor allem in der Recherche und Vorformulierung. Prüfung und Abnahme durch unsere Redaktion.