Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 10.06.2026 · 10 min Lesezeit

S3-Speicher selbst hosten nach dem MinIO-Aus: Garage und RustFS im Vergleich (+ Setup)

MinIO ist archiviert. Die Anleitung vergleicht Garage und RustFS, richtet Garage 2.4.1 als restic-Ziel ein, zeigt RustFS 1.0.1 mit Object Lock und den Umzug aus MinIO mit rclone.

Geprüft am 14.10.2026 · für Garage 2.4.1, RustFS 1.0.1

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Server und Speichersystem mit Kupferkabeln im Regal, vorne eine abschließbare Metallkassette, Abendlicht über Bergen

MinIO war lange der Standard für selbst betriebenen S3-Speicher. Das Projekt hat die Weboberfläche der Community-Edition 2025 stark beschnitten, ist dann in den Wartungsmodus gegangen, und das GitHub-Repository minio/minio ist seit April 2026 archiviert; die README verweist auf die AIStor-Editionen. Wer S3 weiter ohne Lizenzkosten betreiben will, braucht einen Nachfolger. Diese Anleitung vergleicht die beiden Rust-Projekte Garage und RustFS, richtet Garage 2.4.1 als Backup-Ziel für restic ein, zeigt RustFS 1.0.1 mit Object Lock und zieht Daten aus einem bestehenden MinIO mit rclone um.

Voraussetzungen

  • Linux-Server oder VPS mit Docker Engine und Compose-Plugin (siehe Docker installieren), x86_64 oder ARM64.
  • 1 CPU-Kern und 1 GB RAM reichen für einen der beiden Dienste. Im Test belegte Garage rund 60 MB, RustFS rund 130 MB im Leerlauf.
  • Speicherplatz für die Daten plus Reserve. Garage verlangt beim Einrichten eine Kapazitätsangabe, RustFS nutzt das eingebundene Verzeichnis.
  • restic ab 0.16 auf dem zu sichernden Rechner (im Test 0.19.1), für den Umzug rclone (im Test 1.75.2).
  • Port 3900 (Garage) bzw. 9000 (RustFS) vom Backup-Client erreichbar. Außerhalb des eigenen Netzes nur über VPN oder einen Reverse-Proxy mit TLS.

Schritt 1: Garage oder RustFS auswählen

KriteriumGarage 2.4.1RustFS 1.0.1
LizenzAGPL-3.0Apache-2.0
Stabil seit1.0 im Jahr 2024, Projekt seit 20201.0.0 am 16.09.2026
RAM im Testca. 60 MBca. 130 MB
Weboberflächenein, CLI und Admin-APIja, Konsole auf Port 9001
Versionierung, Object Lockneinja, im Test geprüft
Ports3900 S3, 3901 Cluster, 3903 Admin9000 S3, 9001 Konsole (wie MinIO)
Mehrere KnotenReplikation über Zonen, auch über Standorteverteilter Modus mit Erasure Coding
Passt fürschlankes Backup-Ziel, kleine ServerMinIO-Umsteiger, unveränderliche Backups

Faustregel: Für ein einfaches restic-Ziel auf einem kleinen Server ist Garage die sparsamere Wahl. Brauchen Sie Object Lock gegen Ransomware oder eine Weboberfläche für Kollegen ohne Kommandozeile, nehmen Sie RustFS und testen es zunächst parallel mit unkritischen Daten. Eine weitere Alternative mit Weboberfläche beschreibt die Anleitung SeaweedFS mit Docker.

Verifizieren: Sie wissen, ob Sie Object Lock oder eine Weboberfläche brauchen, und haben sich danach für Garage (Schritte 2 bis 5) oder RustFS (Schritt 6) entschieden.

Schritt 2: Garage konfigurieren und starten

Garage liest seine Einstellungen aus garage.toml. Das rpc_secret sichert die Kommunikation zwischen Knoten, admin_token die Admin-API. Erzeugen Sie die Datei mit Zufallswerten:

mkdir -p ~/garage/meta ~/garage/data && cd ~/garage
cat > garage.toml <<EOF
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"
metadata_auto_snapshot_interval = "6h"

replication_factor = 1

rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "$(openssl rand -hex 32)"

[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.garage.localhost"

[admin]
api_bind_addr = "[::]:3903"
admin_token = "$(openssl rand -base64 32)"
metrics_token = "$(openssl rand -base64 32)"
EOF
chmod 600 garage.toml

metadata_auto_snapshot_interval lässt Garage regelmäßig eine Kopie der Metadaten-Datenbank anlegen. Ohne Metadaten lassen sich die Datenblöcke nicht mehr zuordnen. Dann compose.yaml:

services:
  garage:
    image: dxflrs/garage:v2.4.1
    container_name: garage
    restart: unless-stopped
    ports:
      - "3900:3900"
      - "127.0.0.1:3903:3903"
    volumes:
      - ./garage.toml:/etc/garage.toml:ro
      - ./meta:/var/lib/garage/meta
      - ./data:/var/lib/garage/data

Nur die S3-API auf Port 3900 ist nach außen offen. Die Admin-API bleibt auf localhost, den Cluster-Port 3901 brauchen Sie nur bei mehreren Knoten.

docker compose up -d
docker logs garage --tail 5
docker exec garage /garage status

Verifizieren: Das Log enthält S3 API server listening on http://[::]:3900. garage status listet einen Knoten unter HEALTHY NODES mit NO ROLE ASSIGNED und Version v2.4.1.

Schritt 3: Layout zuweisen, Bucket und Schlüssel anlegen

Garage nimmt erst Daten an, wenn dem Knoten im Layout eine Zone und eine Kapazität zugewiesen sind. Die Kapazität bestimmt die Verteilung bei mehreren Knoten; tragen Sie den Platz ein, den Garage nutzen darf.

NODE=$(docker exec garage /garage node id -q | cut -c1-16)
docker exec garage /garage layout assign -z dc1 -c 500G $NODE
docker exec garage /garage layout apply --version 1
docker exec garage /garage health

docker exec garage /garage bucket create restic-backup
docker exec garage /garage key create restic-key
docker exec garage /garage bucket allow --read --write --owner restic-backup --key restic-key

key create gibt Key ID (beginnt mit GK) und Secret key aus. Notieren Sie beides im Passwortmanager. Später zeigt garage key info restic-key --show-secret das Secret erneut an.

Für einen Testserver gibt es eine Abkürzung: Mit server --single-node --default-bucket als Startbefehl und den Variablen GARAGE_DEFAULT_ACCESS_KEY (muss mit GK beginnen), GARAGE_DEFAULT_SECRET_KEY und GARAGE_DEFAULT_BUCKET legt Garage Layout, Schlüssel und Bucket beim Start selbst an. Im Test setzte die Abkürzung die gesamte freie Plattenkapazität als Layout; für den Dauerbetrieb ist der manuelle Weg übersichtlicher.

Verifizieren: garage health meldet Cluster health: HEALTHY, garage layout show zeigt den Knoten in Zone dc1 mit Ihrer Kapazität, und garage bucket info restic-backup listet den Schlüssel mit den Rechten RWO.

Schritt 4: restic mit Garage verbinden

Legen Sie auf dem zu sichernden Rechner eine Umgebungsdatei an. Die Region muss exakt dem Wert s3_region aus garage.toml entsprechen.

sudo install -d -m 700 /etc/restic
sudo tee /etc/restic/garage.env >/dev/null <<'EOF'
AWS_ACCESS_KEY_ID=GK...
AWS_SECRET_ACCESS_KEY=...
AWS_DEFAULT_REGION=garage
RESTIC_REPOSITORY=s3:http://backup.example.lan:3900/restic-backup
RESTIC_PASSWORD=LANGES-ZUFAELLIGES-PASSWORT
EOF
sudo chmod 600 /etc/restic/garage.env
set -a; . /etc/restic/garage.env; set +a
restic init

Das restic-Passwort verschlüsselt das Repository. Ohne dieses Passwort sind die Daten verloren, bewahren Sie es getrennt vom Server auf. Zusätzliche Optionen für den Bucket-Zugriff brauchte restic im Test nicht.

Verifizieren: restic init meldet created restic repository … at s3:http://…/restic-backup, und restic snapshots zeigt 0 snapshots, ohne Fehler.

Schritt 5: Erstes Backup sichern und Wiederherstellung prüfen

set -a; . /etc/restic/garage.env; set +a
restic backup /etc /home
restic snapshots
restic check
restic restore latest --target /tmp/restore-test --include /etc/hostname
cat /tmp/restore-test/etc/hostname

Im Test lief Sicherung, Prüfung und Wiederherstellung einer Markerdatei fehlerfrei durch. Den Zeitplan mit systemd-Timer oder Cron beschreibt die Anleitung restic-Backups automatisieren.

Sichern Sie auch den Garage-Server selbst: garage.toml und das Verzeichnis meta bei gestopptem Container. Mit replication_factor = 1 gibt es keinen Schutz gegen einen Plattenausfall. Eine zweite Kopie an einem anderen Ort gehört deshalb dazu, siehe 3-2-1-Backup-Strategie.

Verifizieren: restic snapshots zeigt einen Snapshot mit aktuellem Zeitstempel, restic check endet mit no errors were found, und die wiederhergestellte Datei hat den erwarteten Inhalt.

Schritt 6: RustFS mit Weboberfläche und Object Lock

RustFS läuft im Container als Benutzer mit UID 10001. Eingebundene Verzeichnisse müssen diesem Benutzer gehören, sonst bricht der Start mit Rechtefehlern ab. Die offizielle Compose-Datei nutzt rustfsadmin als Standardzugang; setzen Sie eigene Werte.

mkdir -p ~/rustfs/data ~/rustfs/logs && cd ~/rustfs
sudo chown -R 10001:10001 data logs
printf "RUSTFS_ACCESS_KEY=admin%s\nRUSTFS_SECRET_KEY=%s\n" "$(openssl rand -hex 4)" "$(openssl rand -hex 24)" > .env
chmod 600 .env
services:
  rustfs:
    image: rustfs/rustfs:1.0.1
    container_name: rustfs
    restart: unless-stopped
    ports:
      - "9000:9000"
      - "127.0.0.1:9001:9001"
    environment:
      - RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY}
      - RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY}
      - RUSTFS_CONSOLE_ENABLE=true
    volumes:
      - ./data:/data
      - ./logs:/logs
docker compose up -d
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/health

Die Konsole erreichen Sie per SSH-Tunnel (ssh -L 9001:localhost:9001 benutzer@server) unter http://localhost:9001. Sie melden sich mit den Werten aus der .env an und legen Buckets an.

RustFS-Konsole, Seite Buckets mit den Buckets restic-rustfs und worm-test, Schaltfläche Bucket erstellen mit 1 markiert
1 Bucket erstellen legt einen neuen Bucket an, Object Lock lässt sich nur beim Anlegen aktivieren.

Für unveränderliche Backups legen Sie den Bucket mit Object Lock an und setzen eine Standardaufbewahrung. Mit der AWS CLI geht das so:

export AWS_ACCESS_KEY_ID=admin... AWS_SECRET_ACCESS_KEY=... AWS_DEFAULT_REGION=us-east-1
aws --endpoint-url http://127.0.0.1:9000 s3api create-bucket --bucket worm-backup --object-lock-enabled-for-bucket
aws --endpoint-url http://127.0.0.1:9000 s3api put-object-lock-configuration --bucket worm-backup \
  --object-lock-configuration '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":30}}}'

Im Test mit einem Tag Aufbewahrung lehnte RustFS das Löschen einer Objektversion ab: AccessDenied … Object is under COMPLIANCE retention and cannot be deleted until …. Im Modus COMPLIANCE kann auch der Administrator die Frist nicht verkürzen. Wählen Sie die Dauer deshalb passend zu Ihrer Aufbewahrung. restic arbeitete im Test mit RustFS ohne Anpassungen (Backup und restic check fehlerfrei); restic löscht beim forget --prune aber selbst Daten, die Aufbewahrungsfrist muss deshalb zu Ihren restic-Aufbewahrungsregeln passen. Für Ransomware-Schutz mit restic beschreibt die Anleitung Immutable Backups mit restic ein erprobtes Muster.

RustFS-Bucket-Einstellungen, Bereich Datenschutz mit aktivierter Versionierung, Objektsperre und Aufbewahrung im Modus COMPLIANCE für 1 Tag
Bucket-Einstellungen, Datenschutz: Versionierung, Objektsperre und Aufbewahrung sind aktiv.

Verifizieren: /health liefert 200, die Konsole zeigt nach der Anmeldung Ihre Buckets, und get-object-lock-configuration gibt "Mode": "COMPLIANCE" mit Ihrer Frist zurück.

Schritt 7: Daten aus MinIO umziehen

Garage und RustFS übernehmen kein MinIO-Datenverzeichnis. Kopieren Sie die Buckets über die S3-API mit rclone. Legen Sie im Ziel zuerst Bucket und Schlüssel an (Garage: bucket create und bucket allow), dann ~/.config/rclone/rclone.conf:

[minio]
type = s3
provider = Minio
access_key_id = MINIO-ZUGANG
secret_access_key = MINIO-SECRET
endpoint = http://alter-server:9000

[garage]
type = s3
provider = Other
access_key_id = GK...
secret_access_key = ...
endpoint = http://backup.example.lan:3900
region = garage
force_path_style = true
rclone sync minio:altdaten garage:altdaten --progress
rclone check minio:altdaten garage:altdaten
rclone size garage:altdaten

Für RustFS als Ziel nehmen Sie provider = Other mit Endpunkt Port 9000 und den RustFS-Zugangsdaten. Stellen Sie danach die Anwendungen auf den neuen Endpunkt und die neuen Schlüssel um und lassen Sie MinIO erst nach einer Übergangszeit abschalten.

Verifizieren: rclone check meldet 0 differences found und die erwartete Zahl matching files, rclone size zeigt im Ziel dieselbe Objektzahl und Größe wie in MinIO.

Typische Fehler

  • Garage nimmt keine Daten an: Layout fehlt. garage status zeigt NO ROLE ASSIGNED; Schritt 3 ausführen.
  • restic hängt mit Stat: 400 Bad Request und wiederholt minutenlang: Falsche Region. AWS_DEFAULT_REGION muss s3_region aus garage.toml entsprechen. Im Test führte us-east-1 genau zu diesem Bild.
  • AccessDenied bei restic: Schlüssel hat keine Rechte auf den Bucket. garage bucket allow … --key … wiederholen.
  • RustFS startet nicht, permission denied: Verzeichnisse gehören nicht UID 10001. sudo chown -R 10001:10001 data logs.
  • Löschen schlägt in RustFS fehl: Object Lock mit laufender Aufbewahrung. Das ist gewollt; im Modus COMPLIANCE gibt es keinen Weg vorbei.
  • rclone findet den Bucket nicht: Bei Garage force_path_style = true und region = garage setzen.

Häufige Fragen

Kann ich MinIO einfach weiterlaufen lassen?

Eine bestehende Installation funktioniert weiter. Das Repository ist aber archiviert, Sicherheitskorrekturen für die Community-Edition erscheinen dort nicht mehr. Planen Sie den Umzug, statt neu auf MinIO aufzubauen.

Darf ich Garage unter AGPL im Unternehmen nutzen?

Ja. Die AGPL verlangt die Weitergabe des Quellcodes erst, wenn Sie Garage verändern und Dritten als Netzdienst anbieten. Der interne Einsatz als Backup-Ziel ist davon nicht betroffen.

Brauche ich für Garage drei Server?

Nein. Ein Knoten mit replication_factor = 1 genügt als Backup-Ziel. Mehrere Knoten in verschiedenen Zonen bringen Ausfallsicherheit; dann setzen Sie replication_factor = 3 und auf allen Knoten dasselbe rpc_secret.

Gibt es für Garage eine Weboberfläche?

Nicht vom Projekt selbst. Verwaltet wird per garage-CLI oder Admin-API, Inhalte sehen Sie mit S3-Werkzeugen wie rclone. Wer eine Oberfläche braucht, ist mit RustFS besser bedient.

Fazit

Garage ist ein schlankes, unkompliziertes Backup-Ziel für restic, auch auf kleinen Servern. Es verzichtet bewusst auf Versionierung, Object Lock und Weboberfläche. RustFS kommt MinIO am nächsten, mit Konsole, gleichen Ports und Object Lock, ist als stabile Version aber erst wenige Wochen alt und verdient eine Testphase. Den Umzug aus MinIO erledigt rclone in beiden Fällen mit sync und check.

Weiterführende Anleitungen und Quellen