SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-10-21

MinIO auf VPS selbst hosten: S3-Speicher einrichten

MinIO auf einem Ubuntu-24.04-VPS einrichten: geprüften Source-Build kompilieren, systemd konfigurieren, mc nutzen, Presigned URLs erstellen und restic anbinden.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Welche Vorteile Ihnen selbst gehosteter Objektspeicher mit MinIO bietet

MinIO ist ein selbst gehosteter Objektspeicher mit Unterstützung für die Amazon-S3-API. Sie richten restic oder ein S3 SDK auf Ihren eigenen Server und ändern eine Endpoint-Einstellung. Für das Lesen, Schreiben und Auflisten von Objekten sowie für presigned Links ist damit im Alltag alles erledigt. Kompatibel bedeutet jedoch nicht identisch. MinIO implementiert beispielsweise nicht die Objekt-ACLs von Amazon. Die Maintainer haben außerdem erklärt, dass sie dies nicht beabsichtigen. Eine Anwendung, die vom Verhalten dieser ACLs abhängt, benötigt daher mehr als einen neuen Endpoint. Dieser Leitfaden richtet einen einzelnen Node auf Ubuntu 24.04 ein: eine aus verifiziertem Quellcode kompilierte Binärdatei, einen dedizierten Systembenutzer, eine systemd-Unit, die die Root-Anmeldedaten aus der Unit-Datei heraushält, und einen Bucket, in den restic Backups schreibt.

S3 (simple storage service) ist eine HTTP-API und kein Dateisystem. Sie schreiben ein Objekt mit PUT unter einem Schlüssel in einen Bucket und lesen es mit GET wieder aus. In einem Standard-Bucket gibt es keinen partiellen Schreibvorgang und keine Umbenennung. Die Directory-Buckets von Amazons S3 Express One Zone sind eine Ausnahme. Sie bieten eigene Aufrufe zum Anhängen und Umbenennen. Das ist jedoch eine einzelne Storage-Klasse, und nichts in diesem Leitfaden setzt sie voraus. Backup-Tools verwenden das Standardmodell gern, weil ein Objekt entweder vollständig angekommen ist oder nicht.

Ein Node enthält eine Kopie Ihrer Daten. Das ist der damit verbundene Kompromiss. Sie erhalten einen von Ihnen kontrollierten S3-Endpoint zum Preis eines VPS. Gleichzeitig übernehmen Sie alle Aufgaben, die sonst der Cloud-Anbieter erledigt hätte. Dazu gehören der Austausch einer ausgefallenen Festplatte und das Patchen der Serversoftware. Im Abschnitt gegen Ende wird klar beschrieben, wann dieser Kompromiss sinnvoll ist.

Der Stand der MinIO Community Edition im Oktober 2026

Lesen Sie diesen Abschnitt, bevor Sie darauf aufbauen, denn die Situation hat sich kürzlich geändert. Im Mai 2025 entfernte MinIO die Administrationsfunktionen aus der Webkonsole der Community Edition. Im Browser ist nur noch ein Objekt-Browser verfügbar. Buckets und Zugriffsschlüssel werden stattdessen mit dem mc-Befehlszeilenclient verwaltet.

Später im Jahr 2025 stellte MinIO die Veröffentlichung vorkompilierter Community-Binärdateien ein. In der README des Projekts steht, dass die Community Edition ausschließlich als Quellcode verteilt wird. Seit April 2026 ist das minio/minio-Repository außerdem unter dem Hinweis THIS REPOSITORY IS NO LONGER MAINTAINED archiviert. Der alte Download-Server stellt die Community-Dateien ebenfalls nicht mehr bereit. Bei einer Prüfung am 20. Oktober 2026 antwortet jeder dl.min.io-Pfad, den diese Anleitung früher für den Download verwendet hat, mit 410 Gone: die Server-Binärdatei, die Client-Binärdatei und die zugehörigen Prüfsummendateien. Das ist eine beabsichtigte Entfernung und kein Ausfall. Die einzige mc-Binärdatei, die noch auf diesem Server liegt, ist der AIStor Client unter /aistor/mc/release/. Er gehört zur kommerziellen Produktlinie. Auf der Download-Seite von min.io werden jetzt AIStor Server, AIStor Client, AIStor SDK und einige AIStor-Erweiterungen sowie eine kostenlose AIStor-Stufe aufgeführt. Diese beschreibt MinIO als Angebot für Entwickler, Forschende und kleine Organisationen mit eigenständigen Deployments. Ein Community-Build wird nicht angeboten.

Der Quellcode ist weiterhin verfügbar und neuer als die letzte Binärdatei. Das letzte Community-Release ist RELEASE.2025-10-15T17-29-55Z. Es wurde am 16. Oktober 2025 als Security-Release veröffentlicht. Es behebt eine Rechteausweitung durch die Umgehung einer Session-Richtlinie bei Servicekonten und STS. Die Release-Hinweise empfehlen allen Benutzern, sofort zu aktualisieren. Die letzte vorkompilierte Binärdatei stammte aus dem September 2025 und enthielt diesen Fix daher nicht. Diese Anleitung kompiliert das Oktober-Release. Da das Repository archiviert ist, handelt es sich zugleich um den letzten Fix für die Community Edition.

Diese Tatsache bestimmt den weiteren Aufbau der Anleitung. Deshalb lauscht MinIO hier auf 127.0.0.1 und ist nur über einen von Ihnen kontrollierten Proxy aus dem Internet erreichbar.

MinIO-Binary installieren und den Download überprüfen

MinIO ist in Go geschrieben, und die README des Anbieters erstellt es mit einem einzigen go install-Befehl, der Go 1.24 oder neuer benötigt. Installieren Sie Go zuerst aus dem offiziellen Tarball. Am 20. Oktober 2026 ist go1.27.3 die aktuelle stabile Version auf go.dev/dl. Sie wurde am 19. Oktober 2026 mit einer Sicherheitskorrektur für das Paket crypto/x509 veröffentlicht. Der folgende Hash ist der auf dieser Seite für das linux-amd64-Archiv veröffentlichte Hash. Wenn Sie eine neuere Go-Version auswählen, übernehmen Sie den zugehörigen Hash von derselben Seite. Das Flag -f sorgt dafür, dass curl bei einem HTTP-Fehler fehlschlägt, statt die Fehlerseite unter dem angeforderten Namen zu speichern. Andernfalls wird möglicherweise eine 404-Seite entpackt, obwohl eine Archivdatei erwartet wird.

cd /tmp
GOVER=go1.27.3
curl -fsSL "https://go.dev/dl/$GOVER.linux-amd64.tar.gz" -o go.tar.gz

Vergleichen Sie die beiden Hashes. Vergleichen Sie ausschließlich die Hashes.

published=65efbc80fdc1fa2cd2631cad5b481777a68e8725f34e89f50fc6ac714e379b40
downloaded=$(sha256sum go.tar.gz | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"

Beachten Sie genau, was diese Prüfung nachweist. Eine Übereinstimmung bestätigt, dass der Download vollständig ist und während der Übertragung nicht beschädigt oder verändert wurde. Sie bestätigt nicht, dass der Anbieter vertrauenswürdig ist. Das ist ein anderes Problem, das kein sha256sum-Befehl löst.

sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version

Erstellen Sie jetzt die endgültige Community-Version als normaler Benutzer. go install prüft jedes heruntergeladene Modul, einschließlich des MinIO-Quellcodes, anhand der öffentlichen Go-Checksum-Datenbank unter sum.golang.org. Dadurch wird der Build bei einem manipulierten oder ausgetauschten Modul mit einem Sicherheitsfehler beendet, statt eine Binärdatei zu erzeugen.

go install github.com/minio/minio@RELEASE.2025-10-15T17-29-55Z
sudo install -o root -g root -m 755 ~/go/bin/minio /usr/local/bin/minio
minio --version
go version -m /usr/local/bin/minio | head -n 3

minio --version gibt DEVELOPMENT.GOGET aus, wo früher ein Release-Name stand, weil go install die Build-Flags nicht anwendet, mit denen der Anbieter seine eigenen Binärdateien versieht. go version -m liest die Modulinformationen, die Go in jede Binärdatei einbettet. Die Zeile mod github.com/minio/minio nennt den Commit, den Sie erstellt haben. Ein Permission denied an dieser Stelle bedeutet, dass der Modus falsch ist. command not found bedeutet, dass /usr/local/bin nicht auf Ihrem PATH vorhanden ist. Wenn auf dem VPS nicht genügend Arbeitsspeicher für die Kompilierung verfügbar ist, führen Sie denselben go install auf einem anderen Linux-System mit derselben Architektur aus und kopieren Sie die Binärdatei anschließend auf den VPS.

Einen Systembenutzer und ein Datenverzeichnis erstellen

MinIO nimmt Uploads aus dem Netzwerk entgegen und sollte daher nicht als root ausgeführt werden. Weisen Sie dem Dienst ein Konto ohne Home-Verzeichnis und ohne Login-Shell zu.

sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user -s /usr/sbin/nologin minio-user
sudo mkdir -p /var/lib/minio/data
sudo chown -R minio-user:minio-user /var/lib/minio
sudo chmod 750 /var/lib/minio

-r erstellt ein Systemkonto mit einer UID unter 1000. Dadurch fällt es nicht in den für Benutzerkonten vorgesehenen Bereich. -M überspringt das Home-Verzeichnis, weil ein Konto, das sich nie anmeldet, dort keine Daten benötigt. Prüfen Sie das Ergebnis mit id minio-user. Mit stat -c '%U %a' /var/lib/minio sollte minio-user 750 ausgegeben werden.

Das Datenverzeichnis muss für diesen Benutzer beschreibbar und nicht nur lesbar sein. Beim ersten Start erstellt MinIO darin ein Verzeichnis .minio.sys, um die eigene Konfiguration zu speichern. Ein Verzeichnis im Besitz von root führt daher dazu, dass MinIO während des Starts mit einer Meldung beendet wird, die auf permission denied endet. Diese Regel gilt für jeden Dienst, den Sie auf diese Weise ausführen. Dienstbenutzer mit minimalen Berechtigungen auf einem VPS behandelt dieses Thema ausführlich.

Root-Zugangsdaten in einer Umgebungsdatei hinterlegen

Die Root-Zugangsdaten gewähren Zugriff auf jeden Bucket. Sie gehören daher nicht in die Unit-Datei, die für alle Benutzer lesbar ist. Erstellen Sie die Datei zuerst mit den richtigen Berechtigungen und schreiben Sie erst danach den Inhalt hinein. So liegt das Passwort auch nicht für einen kurzen Moment in einer lesbaren Datei.

sudo install -o root -g root -m 600 /dev/null /etc/default/minio
printf 'MINIO_ROOT_USER=minio-root\nMINIO_ROOT_PASSWORD=%s\nMINIO_VOLUMES="/var/lib/minio/data"\nMINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"\n' "$(openssl rand -base64 24)" | sudo tee /etc/default/minio > /dev/null
sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio

tee leert eine vorhandene Datei, statt sie neu zu erstellen. Dadurch bleiben die Berechtigungen 600 erhalten und der Eigentümer bleibt root. Das ist beabsichtigt. systemd liest EnvironmentFile als root ein, bevor es die Berechtigungen auf User= reduziert. Das Dienstkonto muss daher seine eigenen Zugangsdaten niemals lesen können. Sobald der Dienst läuft, überprüfen Sie dies mit sudo -u minio-user cat /etc/default/minio. Dieser Befehl muss Permission denied ausgeben.

Vor dem Start sollten Sie zwei Verhaltensweisen von MinIO kennen. Wenn weder MINIO_ROOT_USER noch MINIO_ROOT_PASSWORD in der Umgebung gesetzt ist, verweigert MinIO den Start nicht. Es startet mit den dokumentierten Standardzugangsdaten minioadmin:minioadmin. Das ist das erste Zugangsdatenpaar, das jeder Scanner ausprobiert. Der Dienst wirkt dabei vollständig funktionsfähig. Ein Passwort mit weniger als 8 Zeichen wird dagegen abgelehnt. MinIO beendet sich beim Start mit einer Fehlermeldung, dass die Zugangsdaten ungültig sind. Der Access Key muss mindestens 3 Zeichen und der Secret Key mindestens 8 Zeichen enthalten.

MINIO_VOLUMES ist der Datenpfad, und MINIO_OPTS enthält die Optionen. Eine Bindung an 127.0.0.1 bedeutet, dass außerhalb dieses VPS noch nichts die S3-API erreichen kann. Das ist die richtige Voreinstellung. Sie öffnen den Zugriff später bewusst über einen Proxy, der ein Zertifikat verwendet.

Die systemd-Unit erstellen

Erstellen Sie /etc/systemd/system/minio.service:

[Unit]
Description=MinIO object storage
Documentation=https://github.com/minio/minio
Wants=network-online.target
After=network-online.target

[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

Vor - in EnvironmentFile steht kein führendes Zeichen. Das ist beabsichtigt und kein Tippfehler. Mit dem Bindestrich ignoriert systemd eine fehlende Datei und startet MinIO trotzdem. Eine gelöschte Datei oder ein falsch geschriebener Pfad führt dadurch unbemerkt zu einem Server, der mit minioadmin:minioadmin läuft. Ohne den Bindestrich schlägt die Unit fehl, bevor MinIO überhaupt gestartet wird. journalctl -u minio zeigt dann Failed to load environment files: No such file or directory. Eine Unit, die den Start verweigert, fällt deutlich eher auf als ein Server, der unbemerkt das Standardpasswort akzeptiert.

$MINIO_VOLUMES und $MINIO_OPTS werden absichtlich nicht in Anführungszeichen gesetzt, weil systemd nicht quotierte Variablen an Leerzeichen in einzelne Argumente aufteilt. So werden die vier Wörter in MINIO_OPTS zu vier Argumenten für minio server. LimitNOFILE=65536 erhöht das Dateideskriptorlimit. Jede offene Verbindung und jede geöffnete Datendatei belegt einen Deskriptor. Der Standardwert 1024 ist unter Last schnell ausgeschöpft.

sudo systemctl daemon-reload
sudo systemctl enable --now minio
systemctl is-active minio
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/minio/health/live

is-active sollte active ausgeben. Der Health-Endpunkt sollte mit 200 antworten. journalctl -u minio -n 20 --no-pager zeigt die API-Adresse, an der der Server Verbindungen entgegennimmt. Wenn die Unit wiederholt neu gestartet wird, gibt systemd auf und protokolliert Start request repeated too quickly. Das bedeutet, dass MinIO bei jedem Versuch beendet wird. Der Grund steht in den Zeilen vor dieser Meldung. Lesen Sie daher im Log nach oben.

Für eine stärkere Isolation fügen Sie ProtectSystem=full und ProtectHome=true im Abschnitt [Service] hinzu. Beide Optionen benötigen Mount-Namespaces des Host-Kernels. Bei Container-Virtualisierung mit gemeinsam genutztem Host-Kernel, beispielsweise OpenVZ oder LXC, können sie fehlschlagen. Die Unit meldet dann status=226/NAMESPACE. Entfernen Sie die beiden Zeilen, startet sie. Die Unit selbst ist eine gewöhnliche Unit. systemd-Dienste und Timer auf einem VPS behandelt die übrigen Direktiven.

Installieren Sie mc und weisen Sie einen Roundtrip nach

Der MinIO-Client ist mc. Installieren Sie ihn nicht mit apt install mc. Dieses Paket ist Midnight Commander, ein von MinIO unabhängiger Dateimanager.

dl.min.io stellt weiterhin eine mc-Binärdatei bereit, aber nicht die Community-Version. Der alte Community-Pfad https://dl.min.io/client/mc/release/linux-amd64/mc antwortet mit 410 Gone. MinIO bietet dort inzwischen den AIStor Client unter https://dl.min.io/aistor/mc/release/linux-amd64/mc an. Die AIStor-CLI-Referenz verweist darauf und beschreibt ihn als Client mit exklusiver Funktionalität für lizenzierte AIStor-Serverbereitstellungen. Die Referenz enthält keine Angaben zur Verwendung mit einem Community-Server. Daher verwendet diese Anleitung weiterhin den Community-Client. Das Repository minio/mc ist seit Juli 2026 archiviert. Bauen Sie daraus die letzte Version RELEASE.2025-08-13T08-35-41Z mit derselben Go-Toolchain. Die Prüfsummendatenbank deckt auch diesen Download ab.

go install github.com/minio/mc@RELEASE.2025-08-13T08-35-41Z
sudo install -o root -g root -m 755 ~/go/bin/mc /usr/local/bin/mc

Registrieren Sie den Server als Alias und übertragen Sie anschließend ein Objekt über ihn.

MINIO_PASS=$(sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio)
mc alias set local http://127.0.0.1:9000 minio-root "$MINIO_PASS"
mc mb local/backups
echo "hello object storage" > /tmp/hello.txt
mc cp /tmp/hello.txt local/backups/hello.txt
mc ls local/backups
mc cat local/backups/hello.txt

mc ls sollte hello.txt mit seiner Größe auflisten, und mc cat sollte hello object storage ausgeben. Dieser Roundtrip ist der eigentliche Nachweis, dass der Server funktioniert. Dabei werden dieselben signierten S3-Anfragen ausgeführt wie bei jedem anderen Client. mc admin info local gibt den Serverstatus aus, wenn Sie eine zusätzliche Prüfung wünschen.

Führen Sie jetzt eine weitere Prüfung durch, solange der Server noch leer ist.

mc alias set defaultcheck http://127.0.0.1:9000 minioadmin minioadmin

Dieser Befehl muss fehlschlagen. Wenn er erfolgreich ist, hat die Umgebungsdatei den Prozess nicht erreicht und Ihr Server läuft mit den Standardanmeldedaten. Beheben Sie das, bevor irgendetwas anderes auf den Server zugreift.

mc speichert Aliase in ~/.mc/config.json als Klartext. Dadurch liegen diese Anmeldedaten im Home-Verzeichnis der Person, die den Befehl ausgeführt hat. Wenn Sie mc unter sudo ausführen, landen die Root-Anmeldedaten in /root/.mc/config.json. Bewahren Sie den Root-Alias in einem Administratorkonto auf und geben Sie jeder Anwendung einen eigenen Schlüssel.

Einen einzelnen Gegenstand mit einer vorab signierten URL bereitstellen

Eine vorab signierte URL ist ein gewöhnlicher HTTPS-Link mit einer angefügten Signatur und Ablaufzeit. Jeder, der den Link besitzt, kann diesen einen Gegenstand ohne Konto und ohne Client abrufen.

mc share download --expire 12h local/backups/hello.txt

Die Ausgabe enthält X-Amz-Signature und X-Amz-Expires in der Abfragezeichenfolge. Zwei Aspekte überraschen viele Anwender. Der Link wird aus dem Endpunkt des verwendeten Alias erstellt. Ein Alias auf 127.0.0.1 erzeugt daher einen Link, den nur diese Maschine öffnen kann. Erstellen Sie für Links, die Sie weitergeben möchten, einen zweiten Alias auf Ihrem öffentlichen Hostnamen. Außerdem gibt es keine Möglichkeit, einzelne Links zu widerrufen. Die Signatur bleibt gültig, bis sie abläuft oder der Schlüssel, mit dem sie erstellt wurde, entfernt oder geändert wird. Bei einem mit den root-Anmeldedaten signierten Link müssen Sie dafür die root-Anmeldedaten rotieren. Eine kurze Ablaufzeit ist daher die praktikable Kontrolle. Sieben Tage sind das Maximum, das das S3-Signaturformat zulässt.

Restic einen eigenen Schlüssel und Bucket zuweisen

Die Root-Zugangsdaten können jeden Bucket lesen und löschen. Ein Backup-Job darf sie daher nicht verwenden. Erstellen Sie einen Bucket, eine auf diesen Bucket beschränkte Policy und einen Benutzer ohne weitere Berechtigungen.

mc mb local/restic
cat > /tmp/restic-rw.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:ListBucket", "s3:GetBucketLocation"],
      "Resource": ["arn:aws:s3:::restic"]
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": ["arn:aws:s3:::restic/*"]
    }
  ]
}
EOF
RESTIC_KEY=$(openssl rand -base64 24)
mc admin policy create local restic-rw /tmp/restic-rw.json
mc admin user add local restic-backup "$RESTIC_KEY"
mc admin policy attach local restic-rw --user restic-backup

MinIO enthält eine integrierte readwrite-Policy. Damit wäre ein Befehl weniger erforderlich gewesen. Sie gewährt jedoch vollständigen Zugriff auf jeden Bucket auf dem Server. Die obige Policy nennt den Bucket absichtlich zweimal: einmal als arn:aws:s3:::restic, damit das Auflisten des Buckets funktioniert, und einmal als arn:aws:s3:::restic/* für die darin enthaltenen Objekte. In S3 sind ein Bucket und seine Objekte getrennte Ressourcen. Eine Policy, die nur eine dieser Ressourcen nennt, schlägt daher auf eine Weise fehl, die wie ein defekter Client aussieht.

Testen Sie die Einschränkung, bevor Sie ihr vertrauen.

mc alias set resticuser http://127.0.0.1:9000 restic-backup "$RESTIC_KEY"
mc ls resticuser/restic
mc ls resticuser/backups

Der erste ls-Aufruf ist erfolgreich. Der zweite schlägt mit Access Denied fehl. Eine Policy, die Sie nicht getestet haben, ist nur eine Vermutung.

Konfigurieren Sie restic jetzt für die Verwendung dieses Buckets. restic liest die S3-Zugangsdaten aus den standardmäßigen AWS-Umgebungsvariablen. Eine restic-spezifische Datei für Zugangsdaten ist daher nicht erforderlich.

sudo apt install -y restic
export AWS_ACCESS_KEY_ID=restic-backup
export AWS_SECRET_ACCESS_KEY="$RESTIC_KEY"
restic -r s3:http://127.0.0.1:9000/restic init
restic -r s3:http://127.0.0.1:9000/restic backup /etc
restic -r s3:http://127.0.0.1:9000/restic snapshots

restic init fordert ein Repository-Passwort an. Dieses Passwort verschlüsselt das Repository. MinIO speichert daher nur Chiffretext. Wenn Sie das Passwort verlieren, ist auch das Backup verloren. Ein von einem systemd-Timer gestarteter Lauf hat kein Terminal für die Passworteingabe. Speichern Sie RESTIC_PASSWORD_FILE deshalb in einer Datei mit Modus 600, damit geplante Backups funktionieren.

Eine Regel für den Speicherort ist wichtiger als jeder vorherige Befehl. Ein restic-Repository auf demselben VPS wie die geschützten Daten schützt Sie vor einem fehlerhaften rm, aber vor nichts anderem. Der MinIO-Knoten sollte auf einer anderen Maschine laufen, idealerweise in einer anderen Region. restic-Backups auf einem VPS behandelt darauf aufbauend die Zeitplanung und Aufbewahrung.

TLS-Terminierung mit nginx

MinIO läuft auf localhost, daher ist nginx die öffentlich erreichbare Oberfläche. Stellen Sie das Zertifikat zuerst wie unter Let's-Encrypt-Zertifikate mit certbot und nginx beschrieben aus und verwenden Sie anschließend diesen Server-Block.

server {
    listen 443 ssl;
    server_name s3.example.com;

    ignore_invalid_headers off;
    client_max_body_size 0;
    proxy_buffering off;
    proxy_request_buffering off;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 300;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;
        proxy_pass http://127.0.0.1:9000;
    }
}

Mehrere dieser Zeilen sind entscheidend. client_max_body_size 0 hebt das standardmäßige Limit von 1 MB für den Request-Body auf. Andernfalls weist nginx jeden größeren Upload mit 413 Request Entity Too Large zurück, bevor MinIO die Anfrage überhaupt sieht. proxy_request_buffering off leitet den Upload direkt weiter. Standardmäßig wird die gesamte Anfrage zuerst in eine temporäre Datei geschrieben. Ein großes Objekt benötigt dann doppelt so viel Speicherplatz auf dem Datenträger. proxy_set_header Host $http_host ist die schwierige Stelle: Eine S3-Signatur umfasst den Header Host. Wenn ein Proxy diesen Header umschreibt, schlägt jede Anfrage mit SignatureDoesNotMatch fehl, obwohl das Zugriffsprotokoll eine normal eingehende Anfrage zeigt.

Teilen Sie MinIO außerdem seinen öffentlichen Namen mit. Dadurch verweisen die generierten Links auf den Proxy statt auf localhost.

echo 'MINIO_SERVER_URL=https://s3.example.com' | sudo tee -a /etc/default/minio
sudo systemctl restart minio

Die Firewall bleibt übersichtlich. Erlauben Sie SSH und HTTPS. Für die Ports 9000 und 9001 darf es überhaupt keine Regel geben, weil eine an 127.0.0.1 gebundene Adresse unabhängig von der Firewall-Konfiguration von einem anderen Rechner aus nicht erreichbar ist. Grundlagen der ufw-Firewall auf einem VPS enthält die Befehle.

Wann ein Single-Node-MinIO ausreicht und wann Sie echtes S3 benötigen

Single-Node bedeutet hier ein Laufwerk. Es gibt daher weder Parität noch eine zweite Kopie innerhalb des Deployments. Die Haltbarkeit jedes Objekts entspricht der Haltbarkeit der Festplatte eines einzelnen VPS. Die eigene Dokumentation von MinIO, die seit der Abschaltung der gehosteten Community-Dokumentation im Oktober 2025 nur noch als Quelle im Repository minio/docs vorliegt, beschreibt ein Standalone-Deployment als für frühe Entwicklungs- und Evaluierungsphasen vorgesehen. Außerdem wird davon abgeraten, es in der Produktion einzusetzen. Object Lock kann für einen Bucket aktiviert werden. Auf einem einzelnen VPS verhindert dies jedoch nur das Löschen über die S3 API. Jeder Benutzer mit root-Zugriff auf die Maschine kann die Dateien auf dem Datenträger weiterhin löschen. Versprechen Sie daher für dieses Setup keine unveränderliche Aufbewahrungsrichtlinie.

Als restic-Ziel auf einem zweiten VPS in einer anderen Region ist es gut geeignet. Das gilt auch als S3-Endpunkt für Entwicklungsarbeiten und CI-Artefakte, wenn der Verlust eines Buckets lediglich einen erneuten Build erfordert. Für Benutzer-Uploads in einer kleinen Anwendung ist es ebenfalls vertretbar, sofern Sie für den Wiederherstellungsplan verantwortlich sind und eine Wiederherstellung tatsächlich getestet haben.

Wählen Sie Managed S3, wenn ein Vertrag oder eine Aufsichtsbehörde Object Lock oder eine Haltbarkeit über mehrere Regionen verlangt. Das gilt auch, wenn Sie nicht um 03:00 Uhr benachrichtigt werden möchten, weil ein Datenträger vollgelaufen ist. Der eingefrorene Quellcode ist ein weiterer sachlicher Grund. Am 20. Oktober 2026 ist die Community Edition archiviert und wird nicht mehr gepflegt. Ihre letzte Version, RELEASE.2025-10-15T17-29-55Z, ist die Version, die dieses Handbuch kompiliert. Danach werden keine Fehler mehr behoben. Wer sie einsetzt, akzeptiert das oder wechselt zu MinIOs kommerzieller AIStor-Linie oder zu einem anderen selbst gehosteten Objektspeicher. Der Vergleich selbst gehosteter MinIO-Alternativen hilft bei dieser Entscheidung.

Eine Grenze sollte ausdrücklich genannt werden, weil sie häufig relevant ist. Objektspeicher ist keine Datenbank. In einem Standard-Bucket ersetzt jeder Schreibvorgang ein vollständiges Objekt. Selbst der von Amazon für S3 Express One Zone hinzugefügte Append-Aufruf fügt Daten nur am Ende an. Eine aktive SQL-Datei in einem S3-Bucket ist daher langsam und unsicher. Belassen Sie die Datenbank auf dem lokalen Datenträger und sichern Sie sie stattdessen in den Bucket. SQLite in der Produktion auf einem VPS betreiben beschreibt diese Aufteilung.

Fehlerfälle und die angezeigten Meldungen

Die Unit schlägt direkt nach systemctl enable --now fehl. Lesen Sie journalctl -u minio -n 30 --no-pager. Failed to load environment files: No such file or directory bedeutet, dass /etc/default/minio in der Unit fehlt oder der Pfad falsch geschrieben ist. Eine Meldung, die mit permission denied endet, bedeutet, dass das Datenverzeichnis für das Dienstkonto nicht beschreibbar ist. Prüfen Sie daher, ob stat -c '%U' /var/lib/minio/data den Wert minio-user ausgibt.

minioadmin:minioadmin kann sich weiterhin anmelden. Die Umgebungsdatei wurde dem Prozess nicht übergeben. Stellen Sie sicher, dass die Unit EnvironmentFile=/etc/default/minio enthält, führen Sie sudo systemctl daemon-reload aus und starten Sie den Dienst anschließend neu. MinIO liest die Root-Anmeldedaten einmal beim Start ein. Änderungen an dieser Datei bleiben ohne Neustart daher wirkungslos.

Address already in use beim Start. Ein anderer Prozess verwendet Port 9000. Ermitteln Sie ihn mit sudo ss -ltnp | grep :9000, bevor Sie den Port von MinIO ändern.

Uploads über 1 MB schlagen über den Proxy fehl. nginx hat 413 Request Entity Too Large zurückgegeben, und MinIO hat die Anfrage nie erhalten. Setzen Sie client_max_body_size 0 im Server-Block.

SignatureDoesNotMatch. Entweder ist der Secret Key falsch, oder etwas zwischen dem Client und MinIO hat den Host-Header geändert. Dieser Header ist Bestandteil der Signatur.

RequestTimeTooSkewed. Die Uhr des Clients oder des Servers geht falsch. Jede signierte S3-Anfrage enthält einen Zeitstempel. MinIO lehnt wie Amazon S3 eine per Header signierte Anfrage ab, deren Zeitstempel mehr als 15 Minuten von der eigenen Uhrzeit abweicht. Presigned Links werden stattdessen anhand ihrer Ablaufzeit geprüft. Prüfen Sie timedatectl und stellen Sie sicher, dass die Zeitsynchronisierung aktiv ist.

Access Denied für einen Bucket, von dessen Existenz Sie wissen. Der Schlüssel ist auf einen anderen Bucket beschränkt. Geben Sie mit mc admin policy info local restic-rw aus, welche Zugriffe die Policy tatsächlich erlaubt, und vergleichen Sie den Bucket-Namen in den Resource-Zeilen.

FAQ

Ist ein einzelner MinIO-Knoten für echte Backups ausreichend?

Er ist als restic-Ziel ausreichend, wenn er auf einer anderen Maschine als den zu schützenden Daten läuft. Als einzige Kopie ist er nicht ausreichend. Bei einer Bereitstellung mit nur einem Laufwerk gibt es keine Parität. Daher existiert innerhalb von MinIO keine zweite Kopie. Wenn dieses VPS-Laufwerk Daten verliert, sind die Objekte nicht mehr verfügbar. Verwenden Sie ein zweites Ziel an einem anderen Ort. Stellen Sie mindestens einmal aus beiden Zielen wieder her, damit Sie wissen, dass der Prozess funktioniert.

Warum schlägt sha256sum -c bei der Prüfsummendatei von MinIO fehl?

Diese Datei finden Sie nur in einer früher gespeicherten Kopie. Beim Prüfen am 20 October 2026 hat dl.min.io für jede Community-Binärdatei und jede Prüfsummendatei 410 Gone geliefert. Die Bezeichnung nach dem Hash in dieser Datei nennt das Release, beispielsweise minio.RELEASE.2025-09-07T16-13-09Z. Die heruntergeladene Datei heißt normalerweise minio. sha256sum -c sucht nach einer Datei mit dem in der Prüfsummendatei angegebenen Namen. Es findet diese Datei nicht und meldet No such file or directory und WARNING: 1 listed file could not be read. Der Download ist in Ordnung. Vergleichen Sie die Hash-Zeichenfolgen direkt. Ignorieren Sie die Bezeichnung, da sie keine sicherheitsrelevante Bedeutung hat.

Wo ist die MinIO-Administrationskonsole im Web geblieben?

MinIO hat im May 2025 die Administrationsfunktionen aus der Konsole der Community Edition entfernt. In der Weboberfläche ist ein Objektbrowser geblieben. Buckets und Benutzer werden jetzt mit dem mc-Client verwaltet, beispielsweise mit den Befehlen mc admin user add und mc admin policy attach. Das ist in der Community Edition der vorgesehene Weg und kein Behelf. Deshalb führt dieser Leitfaden alle Aktionen über die Kommandozeile aus.

Wie verweise ich mit restic auf MinIO als S3-Backend?

Setzen Sie AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY auf einen MinIO-Zugriffsschlüssel und das zugehörige Geheimnis. Verwenden Sie anschließend eine Repository-Zeichenfolge der Form s3:https://s3.example.com/restic. Das letzte Pfadelement ist dabei der Bucket-Name. Erstellen Sie den Bucket vorher mit mc mb. Ein Schlüssel, der auf einen einzelnen Bucket beschränkt ist, darf keine Buckets erstellen. restic verschlüsselt alle Daten vor dem Upload mit dem eigenen Repository-Passwort. MinIO speichert daher Chiffretext und erhält niemals Ihre Dateien.

Muss ich MinIO hinter nginx betreiben?

Sie benötigen TLS (Transport Layer Security), sobald sich ein Client nicht auf derselben Maschine befindet. Ohne TLS wird jedes Objekt zusammen mit der Access-Key-ID und der Anfrage-Signatur im Klartext über das Netzwerk übertragen. Der geheime Schlüssel verlässt den Client nicht. Für die Berechnung der Signatur wird er nur lokal verwendet. Jeder, der den Netzwerkpfad kontrolliert, kann Ihre Daten trotzdem lesen und eine aufgezeichnete Anfrage wiederholen, solange ihr Zeitstempel gültig ist. Ein Proxy auf Port 443 mit einem Zertifikat von certbot ist der einfachste Weg zu TLS. Außerdem bleibt die Zertifikatserneuerung von MinIO getrennt. MinIO kann TLS auch selbst terminieren, wenn Sie --certs-dir auf ein Verzeichnis mit public.crt und private.key verweisen lassen. Dann benötigt das Dienstkonto Lesezugriff auf den erneuerten privaten Schlüssel. Das verursacht zusätzlichen Aufwand für dasselbe Ergebnis.

War dieser Artikel hilfreich?