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

MinIO S3 selbst hosten mit Docker: Compose-Anleitung mit Traefik und HTTPS

Du willst MinIO als S3-kompatiblen Object Storage selbst hosten? Diese Anleitung zeigt dir Schritt für Schritt, wie du MinIO mit Docker Compose und Traefik samt automatischem HTTPS aufsetzt und als Backup-Ziel nutzt.

Ein realistisches Server-Rack in einem Rechenzentrum mit leuchtenden LED-Displays, auf denen "MinIO S3", "TRAEFIK" und "HTTPS" mit einem Schloss-Symbol stehen.

MinIO S3 selbst hosten mit Docker ist die direkteste Methode, einen vollwertigen, S3-kompatiblen Object Storage auf dem eigenen Server zu betreiben, ohne von einem Cloud-Anbieter abhängig zu sein. In dieser Anleitung richtest du MinIO mit Docker Compose ein, stellst es hinter einen Traefik-Reverse-Proxy mit automatischem HTTPS und bereitest es als S3-Endpoint für Backup-Tools wie Restic, Kopia oder rclone vor. Die Anleitung richtet sich an Admins und die Selfhosting-Szene, die einen privaten, kostenkontrollierten Speicher für Backups, Container-Registries oder Anwendungs-Uploads brauchen.

Kurzfassung: MinIO-Container per Docker Compose starten, Daten in einem persistenten Volume unter /data ablegen, API (Port 9000) und Console (Port 9001) über Traefik-Labels mit TLS verfügbar machen, mit der mc-CLI Buckets und IAM-User anlegen und den Endpoint anschließend als S3-Backup-Ziel verwenden.Was ist MinIO und warum selbst hosten?

MinIO ist ein hochperformanter, S3-kompatibler Object Storage, der unter der GNU AGPL v3 steht. Die API spricht das gleiche Protokoll wie Amazon S3, sodass jedes Tool, das mit S3 umgehen kann, ohne Anpassung auch mit MinIO funktioniert. Du brauchst lediglich einen Endpoint, einen Access Key und einen Secret Key.

Selbst hosten lohnt sich aus mehreren Gründen: volle Datenhoheit (kein Datenabfluss in eine fremde Cloud), planbare Kosten ohne Egress-Gebühren und die Möglichkeit, den Storage direkt neben deine anderen Container zu stellen. Typische Einsatzzwecke sind Backup-Ziele, das Ablegen von Anwendungs-Uploads, eine private Container-Image-Registry-Ablage oder ein S3-Cache für CI-Pipelines.

MinIO besteht aus zwei wesentlichen Komponenten: der S3-API auf Port 9000, über die Programme Objekte lesen und schreiben, und der MinIO Admin Dashboard (Console) auf Port 9001, einer Web-Oberfläche für Buckets, Nutzerverwaltung und Monitoring. Beide Ports trennen wir gleich sauber über zwei Hostnamen hinter Traefik.

Voraussetzungen

  1. Ein Linux-Server (oder NAS/Homeserver) mit installiertem Docker und Docker Compose (Plugin docker compose).
  2. Eine Domain mit zwei DNS-A-/AAAA-Records, z. B. s3.example.com (API) und console.example.com (Dashboard), die auf die öffentliche IP deines Servers zeigen.
  3. Die Ports 80 und 443 nach außen erreichbar (für Let's-Encrypt-Challenge und HTTPS).
  4. Ein bereits laufender oder mit aufzusetzender Traefik v3-Reverse-Proxy.
  5. Grundkenntnisse in der Shell und ein Texteditor für YAML-Dateien.
  6. Ausreichend Plattenplatz für das Daten-Volume (Object Storage wächst mit den Backups).

Falls Docker auf deinem System noch fehlt, folge zuerst unserer Anleitung zur Docker-Installation und komm danach hierher zurück.

Schritt 1: Projektverzeichnis und Verzeichnisstruktur anlegen

Leg ein eigenes Verzeichnis für den Stack an und darin Unterordner für die persistenten Daten. So überlebt dein Object Storage jeden Container-Neustart und jedes Update.

mkdir -p ~/minio/data
cd ~/minio

Der Ordner data wird später als Volume in den Container gemountet und enthält alle Buckets und Objekte. Sichere genau diesen Ordner (oder besser: nutze die unten beschriebene Backup-Integration).

Schritt 2: Traefik-Netzwerk und Reverse-Proxy bereitstellen

MinIO und Traefik kommunizieren über ein gemeinsames externes Docker-Netzwerk. Lege es einmalig an:

docker network create proxy

Falls du Traefik noch nicht betreibst, ist hier eine minimale, eigenständige Docker-Compose-Datei mit aktiviertem ACME/Let's-Encrypt-Resolver. Ersetze die E-Mail-Adresse durch deine eigene.

services:
  traefik:
    image: traefik:v3.3
    container_name: traefik
    restart: unless-stopped
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
      - "--certificatesresolvers.le.acme.email=admin@example.com"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    networks:
      - proxy

networks:
  proxy:
    external: true

Wenn du Traefik bereits anders betreibst, überspringe diesen Schritt und nutze nur den im nächsten Schritt definierten Certresolver-Namen (hier le).

Schritt 3: Zugangsdaten in einer .env-Datei ablegen

Die Root-Zugangsdaten gehören nicht in die Compose-Datei selbst, sondern in eine separate .env-Datei. Setze ein langes, zufälliges Passwort.

MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=BitteHierEinSehrLangesZufallspasswortEinsetzen
MINIO_API_DOMAIN=s3.example.com
MINIO_CONSOLE_DOMAIN=console.example.com

Schütze die Datei vor neugierigen Blicken und lass sie niemals in ein Git-Repository wandern:

chmod 600 .env

Schritt 4: Docker-Compose-Datei für MinIO erstellen

Jetzt das Herzstück. Erstelle eine docker-compose.yml im Ordner ~/minio. Sie startet das offizielle Image minio/minio:latest, mountet das Daten-Volume nach /data, startet die Console explizit auf Port 9001 und definiert zwei Traefik-Router: einen für die S3-API (9000) und einen für das Dashboard (9001).

services:
  minio:
    image: minio/minio:latest
    container_name: minio
    restart: unless-stopped
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
      MINIO_BROWSER_REDIRECT_URL: https://${MINIO_CONSOLE_DOMAIN}
    volumes:
      - ./data:/data
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      # ---- S3-API (Port 9000) ----
      - "traefik.http.routers.minio-api.rule=Host(`${MINIO_API_DOMAIN}`)"
      - "traefik.http.routers.minio-api.entrypoints=websecure"
      - "traefik.http.routers.minio-api.tls.certresolver=le"
      - "traefik.http.routers.minio-api.service=minio-api"
      - "traefik.http.services.minio-api.loadbalancer.server.port=9000"
      # ---- Console / Admin-Dashboard (Port 9001) ----
      - "traefik.http.routers.minio-console.rule=Host(`${MINIO_CONSOLE_DOMAIN}`)"
      - "traefik.http.routers.minio-console.entrypoints=websecure"
      - "traefik.http.routers.minio-console.tls.certresolver=le"
      - "traefik.http.routers.minio-console.service=minio-console"
      - "traefik.http.services.minio-console.loadbalancer.server.port=9001"

networks:
  proxy:
    external: true

Wichtig: Über die Traefik-Labels übernimmt der Reverse-Proxy das komplette TLS-Handling. Der MinIO-Container selbst spricht intern weiterhin HTTP auf 9000/9001, nach außen ist alles per HTTPS verschlüsselt. Die Variable MINIO_BROWSER_REDIRECT_URL sorgt dafür, dass die Console-Weiterleitungen sauber auf deinen HTTPS-Hostnamen zeigen.

Schritt 5: Stack starten und Logs prüfen

Starte den Container im Hintergrund und kontrolliere die Logs, ob MinIO sauber hochkommt.

docker compose up -d
docker compose logs -f minio

In den Logs sollte eine Zeile auftauchen, die die API- und Console-Adressen bestätigt. Traefik holt im Hintergrund das Let's-Encrypt-Zertifikat für beide Hostnamen. Das kann beim ersten Mal eine Minute dauern.

Schritt 6: Admin-Dashboard im Browser öffnen

Rufe nun das MinIO Admin Dashboard auf:

https://console.example.com

Melde dich mit dem MINIO_ROOT_USER und dem MINIO_ROOT_PASSWORD aus deiner .env an. Du landest in der Web-Oberfläche, in der du Buckets, Zugriffsregeln, Nutzer und Monitoring-Daten siehst. Prüfe, ob in der Adressleiste das grüne Schloss (gültiges HTTPS-Zertifikat) erscheint.

Schritt 7: Buckets und Access Keys mit der mc-CLI anlegen

Für Automatisierung und Backups ist die mc-CLI (MinIO Client) bequemer als das Dashboard. Du kannst sie direkt im laufenden Container nutzen, ohne sie separat zu installieren.

Lege zunächst einen Alias an, der auf deinen internen Endpoint zeigt, und erstelle einen Bucket:

docker compose exec minio mc alias set local http://localhost:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"
docker compose exec minio mc mb local/backups

Statt mit den Root-Keys zu arbeiten, legst du für Backups einen eigenen, eingeschränkten Nutzer mit eigenen MinIO Access Keys an. So kannst du den Schlüssel jederzeit widerrufen, ohne den Root-Zugang zu berühren.

# IAM-User mit Access-Key und Secret-Key anlegen
docker compose exec minio mc admin user add local backup-user EinLangerSecretKeyHier

# Eingebaute Policy fuer Lese-/Schreibzugriff zuweisen
docker compose exec minio mc admin policy attach local readwrite --user backup-user

Den Nutzernamen backup-user verwendest du später als Access Key, das gesetzte Secret als Secret Key. Für feinere Rechte kannst du eine eigene Policy als JSON definieren und mit mc admin policy create hinzufügen, die den Zugriff auf einen einzelnen Bucket begrenzt.

Schritt 8: Erster Funktionstest über die S3-API

Prüfe, ob die S3-API über HTTPS antwortet und der neue Nutzer schreiben darf. Setze dazu einen zweiten Alias auf die öffentliche API-Adresse:

docker compose exec minio mc alias set remote https://s3.example.com backup-user EinLangerSecretKeyHier
docker compose exec minio sh -c "echo 'hallo s-edv' > /tmp/test.txt && mc cp /tmp/test.txt remote/backups/test.txt"
docker compose exec minio mc ls remote/backups

Erscheint test.txt in der Liste, funktioniert die Kette aus Traefik, TLS, MinIO und IAM-User vollständig. Falls dein Server seine eigene öffentliche Domain nicht per Loopback auflöst (DNS-Hairpinning), führe denselben Test alternativ mit einer lokal installierten mc direkt vom Host oder von einem externen Rechner aus. Ein zusätzlicher Health-Check liefert der Live-Endpoint:

curl -I https://s3.example.com/minio/health/live

Ein HTTP/2 200 bestätigt, dass die API gesund und über HTTPS erreichbar ist.

Schritt 9: MinIO als S3-Backup-Ziel einbinden

Weil MinIO S3-kompatibel ist, sprichst du es mit gängigen Backup-Tools direkt an. Du brauchst immer drei Angaben: Endpoint (https://s3.example.com), Access Key und Secret Key.

Restic

export AWS_ACCESS_KEY_ID=backup-user
export AWS_SECRET_ACCESS_KEY=EinLangerSecretKeyHier
export RESTIC_REPOSITORY=s3:https://s3.example.com/backups
export RESTIC_PASSWORD=DeinResticRepoPasswort

restic init
restic backup /etc /home

rclone

[minio]
type = s3
provider = Minio
endpoint = https://s3.example.com
access_key_id = backup-user
secret_access_key = EinLangerSecretKeyHier

Danach kopierst du mit rclone sync /pfad minio:backups in deinen Bucket. Kopia funktioniert analog: Als Storage-Typ S3 wählen, Endpoint ohne https:// eintragen und die gleichen Access-/Secret-Keys verwenden. So wird deine MinIO-Instanz zum zentralen Backup-Ziel deiner gesamten Infrastruktur.

Updates und Wartung

Da der Stack das Tag :latest nutzt, ziehst du Updates kontrolliert mit einem Pull und einem Neustart. Plane Updates ein und lies vorab die Release-Notes, da MinIO gelegentlich Verhalten ändert.

docker compose pull
docker compose up -d
docker image prune -f

Für reproduzierbare Deployments empfiehlt es sich, statt :latest ein festes, datiertes Release-Tag zu pinnen und Updates bewusst hochzuziehen. Prüfe nach jedem Update kurz das Dashboard und den Health-Endpoint.

Backup des MinIO-Daten-Volumes

Object Storage selbst ersetzt kein Backup. Sichere regelmäßig den Ordner ~/minio/data sowie deine .env und die Compose-Datei. Für ein konsistentes Snapshot stoppst du den Container kurz oder nutzt mc mirror, um die Buckets auf ein zweites Ziel zu spiegeln:

docker compose exec minio mc mirror --overwrite local/backups /mnt/extern/minio-mirror

Wer professionelle Backup-Software einsetzt, behält zudem aktuelle Patch-Stände im Blick, wie etwa bei Veeam Backup & Replication und CVE-2026-32996.

Troubleshooting

  1. Kein Zertifikat / NET::ERR_CERT: Prüfe, ob die DNS-Records wirklich auf den Server zeigen und Port 80 von außen erreichbar ist. Ohne erreichbaren Port 80 schlägt die TLS-Challenge fehl. Sieh in die Traefik-Logs.
  2. 404 von Traefik: Container und Traefik müssen im selben Netzwerk (proxy) liegen und traefik.enable=true gesetzt sein. Prüfe die Hostnamen in den Router-Rules.
  3. Console lädt, aber Login schlägt fehl: Stimmen MINIO_ROOT_USER und MINIO_ROOT_PASSWORD aus der .env? Nach Änderung der Variablen ist ein docker compose up -d nötig.
  4. Upload-Redirect-Schleife in der Console: Setze MINIO_BROWSER_REDIRECT_URL exakt auf deinen HTTPS-Console-Hostnamen.
  5. SignatureDoesNotMatch beim Backup-Tool: Endpoint, Access Key oder Secret Key falsch. Prüfe, ob das Tool den Endpoint mit oder ohne https:// erwartet.
  6. Daten weg nach Neustart: Das Volume ./data:/data fehlt oder wurde umbenannt. Niemals ohne persistentes Volume starten.

Häufige Fragen

Ist MinIO wirklich vollständig S3-kompatibel?

MinIO implementiert die Amazon-S3-API sehr weitgehend, sodass die allermeisten S3-Clients und Backup-Tools wie Restic, Kopia und rclone ohne Anpassung funktionieren. Du gibst lediglich den MinIO-Endpoint statt der AWS-Adresse an und nutzt deine eigenen Access- und Secret-Keys.

Brauche ich zwingend Traefik für HTTPS?

Nein, aber ein Reverse-Proxy ist die sauberste Lösung. Traefik holt und erneuert Let's-Encrypt-Zertifikate automatisch und terminiert TLS, sodass der MinIO-Container intern unverschlüsselt bleiben darf. Alternativ funktioniert das auch mit Nginx Proxy Manager oder Caddy, nur die Konfiguration unterscheidet sich.

Was ist der Unterschied zwischen Port 9000 und 9001?

Port 9000 ist die programmatische S3-API, über die Tools Objekte lesen und schreiben. Port 9001 ist das MinIO Admin Dashboard, also die Web-Oberfläche für Menschen. In dieser Anleitung trennen wir beide über zwei eigene Hostnamen hinter Traefik.

Sollte ich die Root-Keys für Backups verwenden?

Nein. Lege für jede Anwendung einen eigenen IAM-User mit eigenen MinIO Access Keys und einer eingeschränkten Policy an. So kannst du einzelne Zugänge widerrufen, ohne den Root-Account zu gefährden, und begrenzt den Schaden bei einem geleakten Schlüssel.

Eignet sich MinIO für den produktiven Einsatz?

Für Homeserver, Backups und kleinere Workloads ist ein Single-Node-Setup wie hier völlig ausreichend. Für hohe Verfügbarkeit und größere Datenmengen betreibt man MinIO im verteilten Modus mit mehreren Nodes und Erasure Coding. Das Grundprinzip mit Endpoint, Access Key und Secret Key bleibt identisch.

Fazit

Mit Docker Compose und Traefik hast du in wenigen Schritten einen eigenen, S3-kompatiblen Object Storage aufgesetzt, der über HTTPS abgesichert ist. Die Kombination aus persistentem Daten-Volume, getrennten Hostnamen für API und Dashboard sowie eigenen IAM-Usern macht das Setup sowohl praktisch als auch sicher. Ab jetzt kannst du MinIO als zentrales Backup-Ziel für Restic, Kopia oder rclone nutzen und behältst die volle Kontrolle über deine Daten.

Weiterführende Anleitungen

Wenn du den Unterbau noch aufsetzen musst, hilft dir unsere Anleitung zur Docker-Installation. Wer über souveräne Cloud-Alternativen nachdenkt, findet im Beitrag zur AWS European Sovereign Cloud mit SAP und EC2 G6 spannende Hintergründe zur Datenhoheit. Weitere praxisnahe Tutorials sammeln wir in der Kategorie Cloud.

Quellen

Offizielle Dokumentation und Quellen: MinIO Object Storage for Containers (offizielle Doku), MinIO auf GitHub und Traefik v3 Dokumentation.