← Übersicht  ·  Skripte & Dateien  ·  cloud-host · Speicher

Object Storage

S3-kompatibler Speicher für Backups, App-Assets, statische Seiten und große Medien – Hetzner Object Storage (managed) oder MinIO / Garage selbst gehostet. Client (rclone/aws), Bucket-Policy öffentlich vs privat, Versioning & Lifecycle, statische Website mit Cloudflare davor, App-Integration, Backup-Ziel – und wann was.

Stand: 30. August 2026 Hetzner Object Storage / MinIO ab ~6 €/Monat (1 TB)

Platzhalter einsetzen – nur im Browser

Wann Object Storage

Kein Dateisystem – eine HTTP-API: put, get, list, delete auf Objekte in einem Bucket. Kein Anhängen an eine Datei, jede Operation ein Request. Dafür: praktisch unbegrenzt, pro GB (Gigabyte) bezahlt, HTTP-erreichbar, Versionierung, Lebenszyklus-Regeln, signierte Links.

Speichergut fürnicht für
Object Storage (S3)Backups, App-Uploads, Bilder/Videos, statische Seiten, Logs-Archiv, „w|chst unbegrenzt“Datenbank-Dateien, alles mit vielen kleinen Schreibzugriffen, Home-Verzeichnis
Hetzner VolumeDatenbank, Nextcloud-data, alles was ein Dateisystem braucht„unbegrenzt“ (max 10 TB), teurer pro GB
Storage BoxBackup-Ziel (SFTP/Borg/restic), Kalt-Archiv – günstig pro GBHTTP-Zugriff, App-Integration per SDK (Software Development Kit)
Server-Platteheiß & kleingroß, dauerhaft, geteilt
Backuprestic / rclone → Bucket (Zweitkopie außer Haus, Backup-Guide)
AppUploads landen per SDK im Bucket, der Browser lädt per signiertem Link direkt hoch/runter
Webstatische Seite aus dem Bucket → Cloudflare davor (TLS + eigene Domain)
NextcloudS3 als Primärspeicher (Nextcloud-Guide, Abschnitt 6)

1 Hetzner Object Storage

  1. console.hetzner.com Object Storage Bucket erstellen → Standort fsn1 / nbg1 / hel1, Name seb4u-data (im Hetzner-Namespace eindeutig), Sichtbarkeit privat.
  2. Security S3-Zugangsschlüssel generierenAccess Key + Secret, sofort in den Passwortmanager.
  3. Endpoint: https://fsn1.your-objectstorage.com (Path-Style) oder https://<bucket>.fsn1.your-objectstorage.com (Virtual-Hosted). Region-Name = der Standort.
Preis

Grundgebühr ~5,99 €/Monat inkl. 1 TB (Terabyte) Speicher + 1 TB Traffic. Darüber ~0,0054 €/GB Speicher, ~1,19 €/TB Egress. Monatlich abgerechnet (kein Stunden-Modell). Bei Hetzner nachsehen.

2 Der Client: rclone / aws

Datei · ~/.config/rclone/rclone.conf (bzw. %APPDATA%\rclone\)
[hos]
type = s3
provider = Other
access_key_id = DEIN_ACCESS_KEY
secret_access_key = DEIN_SECRET
endpoint = https://fsn1.your-objectstorage.com
region = fsn1
acl = private
Laptop / Server
winget install Rclone.Rclone        # bzw. apt install rclone

rclone ls    hos:seb4u-data
rclone copy  ./dist hos:seb4u-data/site --progress
rclone sync  ./fotos hos:seb4u-data/fotos --progress   # Achtung: loescht am Ziel, was lokal fehlt
rclone cat   hos:seb4u-data/notiz.txt
rclone link  hos:seb4u-data/report.pdf --expire 1h   # signierter Download-Link
aws-cli (für Bucket-Policy / Lifecycle nötig)
aws configure set default.s3.addressing_style path
$env:AWS_ACCESS_KEY_ID='...'; $env:AWS_SECRET_ACCESS_KEY='...'
aws --endpoint-url https://fsn1.your-objectstorage.com s3 ls s3://seb4u-data

3 Öffentlich vs privat

Standard: alles privat, Zugriff nur mit Key oder signiertem Link. Für statische Assets einen öffentlich lesbaren Prefix.

Datei · policy.json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::seb4u-data/public/*"
  }]
}
Laptop
aws --endpoint-url https://fsn1.your-objectstorage.com \
  s3api put-bucket-policy --bucket seb4u-data --policy file://policy.json

# CORS, falls eine Web-App direkt zugreift
aws ... s3api put-bucket-cors --bucket seb4u-data --cors-configuration file://cors.json
Muster

public/ = öffentlich lesbar (Bilder, CSS, Downloads). Alles andere privat, die App verteilt signierte Links mit Ablauf. Keine Access-Keys in den Browser.

4 Versioning & Lifecycle

Laptop · aws-cli
E=https://fsn1.your-objectstorage.com; B=seb4u-data

# Versionierung an: ueberschriebene/geloeschte Objekte bleiben als alte Version
aws --endpoint-url $E s3api put-bucket-versioning --bucket $B \
  --versioning-configuration Status=Enabled

# Lifecycle: alte Versionen nach 30 Tagen weg, abgebrochene Uploads nach 7 Tagen
aws --endpoint-url $E s3api put-bucket-lifecycle-configuration --bucket $B \
  --lifecycle-configuration file://lifecycle.json
Datei · lifecycle.json
{"Rules":[
  {"ID":"expire-old-versions","Filter":{},"Status":"Enabled",
   "NoncurrentVersionExpiration":{"NoncurrentDays":30},
   "AbortIncompleteMultipartUpload":{"DaysAfterInitiation":7}},
  {"ID":"logs-90-tage","Filter":{"Prefix":"logs/"},"Status":"Enabled",
   "Expiration":{"Days":90}}
]}
Versioning & Kosten

Mit Versioning wird ein delete zum „als alt markieren“ – der Platz (und die Kosten) bleiben, bis die Lifecycle-Regel aufräumt. Ohne Lifecycle-Regel wächst der Bucket unbemerkt. Gut gegen Ransomware / Fehlklick, aber die Regel muss dazu.

5 Statische Website

  1. Dateien hochladen (rclone sync ./dist hos:seb4u-data), Bucket / Prefix öffentlich lesbar (Abschnitt 3).
  2. Website-Konfiguration: aws ... s3 website s3://seb4u-data --index-document index.html --error-document 404.html → ergibt eine Website-URL.
  3. Cloudflare davor (Hetzner OS macht kein TLS auf deiner Domain): in Cloudflare blog als CNAME (Canonical Name) auf die Website-URL, proxied (orange). Cloudflare terminiert TLS (Transport Layer Security), cacht, versteckt den Bucket.
Alternativen für die reine statische Seite

Cloudflare Pages (kostenlos, eigene Domain + TLS eingebaut, Git-Deploy) ist für einen Blog meist einfacher. Object-Storage-Website lohnt, wenn die Seite Teil einer grösseren S3-Nutzung ist oder sehr groß wird.

6 App-Integration

  • Env-Muster (fast jede App/SDK): S3_ENDPOINT, S3_REGION, S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY, oft S3_FORCE_PATH_STYLE=true. Die Keys per SOPS (Secrets OPerationS) verschlüsselt ins Repo.
  • Direkt-Upload aus dem Browser: der Server erzeugt eine presigned PUT-URL (SDK: getSignedUrl('putObject', …)), der Browser lädt direkt in den Bucket – kein Umweg über den Server, keine Keys im Client.
  • Nextcloud: S3 als Primärspeicher – Nextcloud-Guide, Abschnitt 6 (die DB bleibt trotzdem kritisch).
  • Postgres/DB-Backups: pg_dump | rclone rcat hos:seb4u-data/db/$(date +%F).sql.gz aus dem Cron.

7 Backup-Ziel

Server · restic direkt nach S3
export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...
export RESTIC_REPOSITORY="s3:https://fsn1.your-objectstorage.com/seb4u-data/restic"
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic init
restic backup /opt --tag files

Für die Zweitkopie außer Haus aus der Backup-Anleitung besser ein anderer Anbieter (Backblaze B2, Cloudflare R2) – sonst hängt alles an einem Hetzner-Konto. Bucket-Versioning + eine Lifecycle-Regel schützen zusätzlich gegen versehentliches forget.

8 MinIO selbst hosten

Wenn du volle Kontrolle willst, lokal einen S3-Endpoint für die Entwicklung brauchst, oder ohnehin Plattenplatz hast (Volume).

Datei · /opt/stacks/minio/compose.yaml
services:
  minio:
    image: quay.io/minio/minio:latest
    command: server /data --console-address ":9001"
    restart: unless-stopped
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD_FILE: /run/secrets/minio
    volumes: [ /mnt/minio-vol:/data ]     # ein Hetzner-Volume
    secrets: [ minio ]
    networks: [ web ]                       # Traefik: s3.seb4u.com -> :9000, minio.seb4u.com -> :9001
secrets: { minio: { file: ./minio_pw.txt } }
networks: { web: { name: web, external: true } }
Server · mc (MinIO-Client)
mc alias set local https://s3.seb4u.com admin "$(cat minio_pw.txt)"
mc mb local/seb4u-data
mc anonymous set download local/seb4u-data/public
mc admin user add local app "$(openssl rand -base64 18)"     # eigener Key fuer die App
Ein Node = keine Redundanz

MinIO auf einem Server/einer Platte hat keine Ausfallsicherheit über die eine Platte hinaus – genau wie ein Volume. Echtes verteiltes MinIO braucht 4+ Nodes. Für Dev, kleine Projekte oder als Quelle, deren Inhalt du ohnehin sicherst: völlig ok. Die MinIO-Community-Konsole hat 2025 Funktionen verloren – Garage oder SeaweedFS sind leichtgewichtige Alternativen.

9 Betrieb

  • Ein Key je Zweck: Backup-Key (nur ein Prefix, nur put/get), App-Key, dein Admin-Key. Bei Hetzner über Bucket-Policy einschränken. Bei MinIO mc admin policy.
  • Grösse & Requests im Blick: rclone size hos:bucket regelmässig, oder ein Monitoring-Check – Object Storage wächst leise, und Versioning ohne Lifecycle noch leiser.
  • Egress kostet: viele öffentliche Downloads → Cloudflare davor (cacht, spart Egress), oder R2 (kein Egress-Preis).
  • Keys rotieren: neuen Zugangsschlüssel erzeugen, in SOPS tauschen, deployen, alten löschen.
  • Bucket-Namen nach Zweck (seb4u-backup, seb4u-assets) – Policies und Lifecycle sind pro Bucket.

+ Garage, R2, B2

AnbieterModellBesonderheit
Hetzner Object Storagemanaged, ~6 €/Mo (1 TB inkl.)im selben Konto/Netz wie die Server, EU (Europäische Union)
Cloudflare R2~0,015 $/GB/Mo, kein Egress-Preiseigene Domain + TLS nativ, Worker-Integration – ideal für Assets/Website
Backblaze B2~6 $/TB/Mo, erste 10 GB gratisgünstig, S3-kompatibel – guter Zweit-Backup-Ort
Garage (self-hosted)0 € + dein Server/Volumeleichtgewichtig, 1–3 Nodes, von Deuxfleurs – einfacher als MinIO verteilt

+ Kosten

Preise sind Richtwerte. Hetzner hat 2026 zweimal erhöht (zuletzt 15. Juni: CX/CAX +30–40 %, CPX/CCX über 100 %). Aktuelle Server-Preise, alle Nebenposten, ein Rechner und Beispielrechnungen stehen zentral in Kosten & Budget.

Variante~€/MonatAnmerkung
Hetzner Object Storage, < 1 TB~5,991 TB Speicher + 1 TB Traffic inkl.
Backblaze B2, 200 GB Backup~1,2pay-as-you-go, Egress bis 3× Speicher gratis
Cloudflare R2, 100 GB Assets~1,4kein Egress-Preis, ~1 Mio Requests inkl.
MinIO auf 100 GB Hetzner-Volume~4,4 + Serverplus der Server, keine Redundanz
Storage Box BX11 (SFTP, kein S3)~3,811 TB, nur als Backup-Ziel

Faustregel: Backups → Storage Box oder B2, Assets/Website → R2 (kein Egress) oder Cloudflare Pages, „S3-API im eigenen Netz“ → Hetzner Object Storage, Dev/volle Kontrolle → MinIO/Garage.

⌂ Cockpit