SSD Nodes Learn Hosting plans →
Anleitungen Matt ConnorVon Matt Connor · Aktualisiert 2026-08-07

MinIO auf einem VPS selbst hosten: S3 mit Ubuntu 24.04

Installieren Sie MinIO auf einem Ubuntu-24.04-VPS: verifizierte Binärdatei, systemd-Unit, mc-Grundlagen, presigned URLs und restic als S3-Backup-Ziel.

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

Was Ihnen selbst gehosteter Objektspeicher mit MinIO bietet

MinIO ist selbst gehosteter Objektspeicher mit Unterstützung für die Amazon-S3-API. Sie richten restic oder ein beliebiges S3-SDK auf Ihren eigenen Server und ändern nur die Einstellung für den Endpunkt. Für den Client ist kein Unterschied erkennbar. Diese Anleitung erstellt einen einzelnen Knoten unter Ubuntu 24.04: eine verifizierte Binärdatei, einen dedizierten Systembenutzer, eine systemd-Unit, die die Root-Zugangsdaten aus der Unit-Datei heraushält, sowie einen Bucket, in dem restic Sicherungen ablegt.

S3 (Simple Storage Service) ist eine HTTP-API und kein Dateisystem. Sie legen ein Objekt unter einem Schlüssel in einem Bucket ab und rufen es wieder ab. Es gibt weder partielle Schreibvorgänge noch das Umbenennen von Objekten. Backup-Tools kommen mit diesem Modell gut zurecht, weil ein Objekt entweder vollständig angekommen ist oder nicht.

Ein Knoten enthält eine Kopie Ihrer Daten. Das ist der Kompromiss, den Sie eingehen. Sie erhalten einen S3-Endpunkt, den Sie für den Preis eines VPS selbst kontrollieren. Gleichzeitig übernehmen Sie alle Aufgaben, die sonst der Cloud-Anbieter erledigt, vom Ersetzen einer ausgefallenen Festplatte bis zum Aktualisieren der Serversoftware. Im Abschnitt gegen Ende wird ausdrücklich erläutert, wann dieser Kompromiss sinnvoll ist.

Der Status der MinIO Community Edition im Juli 2026

Lesen Sie diesen Abschnitt, bevor Sie darauf aufbauen, da sich die Situation kürzlich geändert hat. 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 daher 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 nun, dass die Community Edition ausschließlich als Quellcode verteilt wird. Die älteren Download-URLs funktionieren weiterhin. Im Juli 2026 liefern sie den Server-Build RELEASE.2025-09-07T16-13-09Z und den Client-Build RELEASE.2025-08-13T08-35-41Z aus. Ein neuerer Community-Build ist nicht erschienen. Die unten genannte Binärdatei ist daher echt und lauffähig, aber eingefroren. Sicherheitskorrekturen, die nach September 2025 veröffentlicht wurden, sind darin nicht enthalten.

Diese eine Tatsache bestimmt den weiteren Aufbau dieser Anleitung. Deshalb lauscht MinIO hier auf 127.0.0.1 und erreicht das Internet ausschließlich über einen von Ihnen kontrollierten Proxy. Wenn Sie Sicherheitskorrekturen zeitnah übernehmen möchten, erstellen Sie MinIO aus dem Quellcode. Die README des Herstellers nennt dafür den einzelnen Befehl go install github.com/minio/minio@latest. Dafür benötigen Sie eine Go-Toolchain. Der Befehl schreibt die Binärdatei nach ~/go/bin/minio. Installieren Sie diese Binärdatei nach /usr/local/bin/minio. Alle weiteren Schritte bleiben unverändert.

MinIO-Binary installieren und den Download überprüfen

Laden Sie das festgelegte Release und die veröffentlichte Prüfsumme herunter. Das Flag -f sorgt dafür, dass curl bei einem HTTP-Fehler fehlschlägt, anstatt die Fehlerseite unter dem angeforderten Namen zu speichern. Andernfalls installieren Sie möglicherweise eine 404-Seite und fragen sich, warum sie sich nicht ausführen lässt.

cd /tmp
REL=RELEASE.2025-09-07T16-13-09Z
curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.$REL" -o minio
curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.$REL.sha256sum" -o minio.sha256sum

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

published=$(awk '{print $1}' minio.sha256sum)
downloaded=$(sha256sum minio | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"

Verwenden Sie hier nicht sha256sum -c minio.sha256sum. Die Bezeichnung nach dem Hash in dieser Datei lautet minio.RELEASE.2025-09-07T16-13-09Z. Wir haben den Download jedoch als minio gespeichert. Daher sucht -c nach einer Datei, die nicht existiert. Der Befehl meldet No such file or directory und anschließend WARNING: 1 listed file could not be read. Das sieht wie ein beschädigter Download aus, ist aber keiner. Die Bezeichnung ist nur ein Name. Der Hash ist der Teil, der die Integrität garantiert.

Machen Sie sich klar, was diese Prüfung beweist. Das Binary und der Hash stammen vom selben Anbieter und wurden über dieselbe Verbindung übertragen. Eine Übereinstimmung beweist daher, dass der Download vollständig war und während der Übertragung nicht beschädigt oder verändert wurde. Sie beweist nicht, dass der Anbieter vertrauenswürdig ist. Das ist ein anderes Problem, das kein sha256sum-Befehl löst.

sudo install -o root -g root -m 755 minio /usr/local/bin/minio
minio --version

minio --version gibt minio version RELEASE.2025-09-07T16-13-09Z gefolgt von einigen Build-Zeilen aus. Ein Permission denied bedeutet hier, dass der Modus falsch ist. command not found bedeutet, dass /usr/local/bin nicht in Ihrem PATH enthalten ist.

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.

mc installieren und einen Roundtrip nachweisen

Der MinIO-Client ist mc. Installieren Sie ihn nicht mit apt install mc. Dieses Paket ist Midnight Commander, ein Dateimanager ohne Bezug zu MinIO.

cd /tmp
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc -o mc
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc.sha256sum -o mc.sha256sum
[ "$(awk '{print $1}' mc.sha256sum)" = "$(sha256sum mc | awk '{print $1}')" ] && echo "checksum ok"
sudo install -o root -g root -m 755 mc /usr/local/bin/mc

Registrieren Sie den Server als Alias und verschieben Sie anschließend ein Objekt über diesen Alias.

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, weil dabei dieselben signierten S3-Anfragen ausgeführt werden wie bei jedem anderen Client. mc admin info local gibt den Serverstatus aus, wenn Sie eine zweite Prüfung benötigen.

Führen Sie jetzt noch eine Prüfung durch, solange das System noch leer ist.

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

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

mc speichert Aliase in ~/.mc/config.json als Klartext. Die Anmeldedaten befinden sich damit im Home-Verzeichnis der Person, die den Befehl ausgeführt hat. Wenn Sie mc unter sudo ausführen, werden die Root-Anmeldedaten in /root/.mc/config.json gespeichert. Belassen Sie den Root-Alias bei einem Administratorkonto und geben Sie jeder Anwendung einen eigenen Schlüssel.

Ein Objekt mit einer presigned URL bereitstellen

Eine presigned URL ist ein gewöhnlicher HTTPS-Link mit einer angehängten Signatur und einem Ablaufzeitpunkt. Jeder, der über den Link verfügt, kann dieses eine Objekt 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. Dabei gibt es zwei Punkte, die häufig überraschen. Der Link wird anhand des Endpunkts im 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 zum Widerrufen. Die Signatur bleibt bis zum Ablaufzeitpunkt gültig. Eine kurze Gültigkeitsdauer ist daher die einzige Kontrollmöglichkeit. 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 ohne Parität. Die eigene Dokumentation von MinIO beschreibt dieses Layout als geeignet für Tests und kleine Workloads ohne Verfügbarkeitsanforderungen. Innerhalb des Deployments gibt es keine zweite Kopie. Die Haltbarkeit jedes Objekts entspricht daher der Haltbarkeit der Festplatte eines einzelnen VPS. Funktionen, die ein verteiltes, per Erasure Coding geschütztes Backend voraussetzen, darunter Bucket-Replikation und Object Locking, gehören zu Deployments mit mehreren Laufwerken. Versprechen Sie daher niemandem eine unveränderliche Aufbewahrungsrichtlinie für dieses Setup.

Als Ziel für restic auf einem zweiten VPS in einer anderen Region ist dieses Setup 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 den Wiederherstellungsplan selbst verantworten und eine Wiederherstellung tatsächlich getestet haben.

Wählen Sie verwaltetes S3, wenn ein Vertrag oder eine Aufsichtsbehörde Object Lock oder Haltbarkeit über mehrere Regionen verlangt. Das gilt auch, wenn Sie nicht um 03:00 Uhr benachrichtigt werden möchten, weil ein Laufwerk vollgelaufen ist. Der eingefrorene Build ist ein weiterer sachlicher Grund. Im Juli 2026 stammt die vorkompilierte Community-Binärdatei aus dem September 2025 und erhält keine Fehlerbehebungen. Wenn Sie sie ausführen, akzeptieren Sie diese Einschränkung. Alternativ müssen Sie den Quellcode selbst kompilieren und das Projekt eigenständig aktuell halten.

Eine Abgrenzung ist wichtig, weil sie häufig übersehen wird. Object Storage ist keine Datenbank. Jeder Schreibvorgang ersetzt ein vollständiges Objekt. Eine aktive SQL-Datei in einem S3-Bucket ist daher langsam und unsicher. Lassen Sie die Datenbank auf dem lokalen Laufwerk und sichern Sie sie stattdessen in den Bucket: SQLite in der Produktion auf einem VPS betreiben beschreibt diese Aufteilung.

Fehlerzustände und angezeigte 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 meldet Sie weiterhin an. Die Umgebungsdatei wurde nie an den Prozess übergeben. Prüfen Sie, ob 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-Zugangsdaten 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 geheime Schlüssel falsch, oder eine Komponente 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 S3-Anfrage enthält einen Zeitstempel und wird außerhalb eines Zeitfensters von 15 Minuten abgewiesen. Prüfen Sie timedatectl und stellen Sie sicher, dass die Zeitsynchronisation 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, was die Richtlinie tatsächlich erlaubt, und vergleichen Sie den Bucket-Namen in den Ressourcenzeilen.

FAQ

Ist ein Single-Node-MinIO für echte Backups ausreichend?

Als restic-Ziel auf einem separaten Rechner, der nicht dieselben Daten hostet wie die zu sichernden Daten, ist es ausreichend. Als einzige Kopie ist es nicht ausreichend. Bei einer Bereitstellung mit nur einem Laufwerk gibt es keine Parität. Daher existiert innerhalb von MinIO keine zweite Kopie. Wenn dieser VPS-Datenträger Daten verliert, sind die Objekte verloren. Verwenden Sie ein zweites Ziel an einem anderen Ort. Führen Sie mindestens einmal eine Wiederherstellung von beiden Zielen durch, damit Sie wissen, dass der Prozess funktioniert.

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

Weil die Bezeichnung nach dem Hash in dieser Datei den Release-Namen minio.RELEASE.2025-09-07T16-13-09Z enthält, während Ihre heruntergeladene Datei normalerweise minio heißt. sha256sum -c sucht nach einer Datei mit dem Namen aus der Prüfsummendatei. Es findet diese Datei nicht und meldet No such file or directory sowie WARNING: 1 listed file could not be read. Der Download ist in Ordnung. Vergleichen Sie die Hash-Zeichenfolgen direkt und ignorieren Sie die Bezeichnung. Sie hat keine sicherheitsrelevante Bedeutung.

Wo ist die Webkonsole für die MinIO-Administration geblieben?

MinIO hat die Administrationsfunktionen im Konsolenbereich der Community Edition im Mai 2025 entfernt. In der Weboberfläche blieb ein Objektbrowser zurück. Buckets und Benutzer werden jetzt mit dem Client mc verwaltet, beispielsweise mit den Befehlen mc admin user add und mc admin policy attach. Das ist in der Community Edition der unterstützte Weg und kein Workaround. Deshalb erledigt diese Anleitung alle Schritte über die Befehlszeile.

Wie richte ich restic so ein, dass MinIO als S3-Backend verwendet wird?

Setzen Sie AWS_ACCESS_KEY_ID und AWS_SECRET_ACCESS_KEY auf einen MinIO-Zugriffsschlüssel und das zugehörige Secret. 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 zuerst 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 keinen Zugriff auf Ihre Dateien.

Muss ich MinIO hinter nginx betreiben?

Sobald sich ein Client nicht auf demselben Rechner befindet, benötigen Sie TLS (Transport Layer Security). S3-Zugangsdaten und Objektdaten werden beide innerhalb der Anfrage übertragen. Ein Proxy auf Port 443 mit einem von certbot ausgestellten Zertifikat ist dafür die einfachste Lösung. Die Zertifikatserneuerung bleibt dabei 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 jedoch Lesezugriff auf den erneuerten privaten Schlüssel. Das verursacht zusätzlichen Aufwand bei gleichem Ergebnis.