Hetzner Object Storage — Bucket-Inventar
S3-API-kompatibel, EU-only (fsn1, nbg1, hel1), pay-per-use. Bucket-Konvention analog buckets, aber mit Hetzner-Quirks (kein Replication, kein Storage-Class-Wechsel, Object-Lock nur bei Bucket-Erstellung aktivierbar).
Buckets pro Project
av-<industriekunde-slug> (geplant, in Anlage)
Aus plan Unit 3:
| Bucket | Status | Region | Zweck | Settings | Lifecycle |
|---|---|---|---|---|---|
<kunde-slug>-data | tbd | nbg1 oder fsn1 (= App-Server-Region) | App-Daten + age-encrypted Backups (WAL-G, pg_dump) | Versioning enabled, Public Access blockiert, Object-Lock NICHT aktiviert (DSGVO-Art-17-Löschbarkeit) | Noncurrent-Versions Glacier-Äquivalent 30d, Expire 365d, Multipart-Cleanup 7d |
<kunde-slug>-audit | tbd | nbg1 oder fsn1 | LLM-Audit-Logs (age-encrypted JSONL.gz pro Stunde) + sonstige Audit-Trails | Versioning enabled, Public Access blockiert, Object-Lock Compliance-Mode Default-Retention 2555 Days (7y HGB) — Aktivierung GATED auf Lead-Briefing-PII-Klassifikation (D-PLAN-12) | Current-Objects Expire 2555d, Noncurrent-Versions Expire 365d, Multipart-Cleanup 7d |
<kunde-slug>-test-objectlock | tbd | nbg1 oder fsn1 | Vor Prod-Bucket-Anlage testen ob Object-Lock-Mechanik richtig konfiguriert (Default 1-Day-Retention) — wegwerf-Bucket | Object-Lock 1-Day-Retention, Versioning | manuell löschen nach Test |
Werte-Double-Check vor Anlage: Retention-Days = 2555 (NICHT 25550 = 70 Jahre!). Screenshot der Console-Konfig vor Commit, zweite Person/Claude reviewen. Object-Lock ist irreversibel — Setup-Fehler kostet 7 Jahre. (Security-Audit-F-14)
Bucket-Anlage — Step-by-Step
- Hetzner Cloud Console → Project wählen → Object Storage → Add Bucket
- Name nach Konvention:
<kunde-slug>-<zweck>(z.B.acme-data) - Region: gleiche wie der App-Server (gleicher Project-Region — kein Cross-Region-Egress)
- Object Lock: nur aktivieren wenn der Bucket-Zweck Compliance-Audit-Trail ist (z.B.
<kunde>-audit). Achtung: nicht nachträglich aktivierbar! Wenn nicht klar → erst Test-Bucket - Versioning: enabled (Pflicht — Lifecycle funktioniert nicht bei suspended Versioning)
- Public Access: blockiert (Default)
- Access Keys generieren (Project → Security → S3 Credentials):
<kunde-slug>-data-rwfür App-Server (Read + Write auf data-Bucket)<kunde-slug>-audit-writefür App-Server (NUR PutObject auf audit-Bucket)<kunde-slug>-audit-read-mfafür Marvin-IAM-User mit MFA (Read-only auf audit-Bucket, nur für Audit-Recherche)
- Keys in 1Password speichern:
Hetzner / <project> / s3-keys-<rolle> - Lifecycle-Rules setzen via
aws s3api put-bucket-lifecycle-configuration --endpoint-url https://<region>.your-objectstorage.com(S3-API-kompatibel) - In diese Tabelle oben eintragen + im Project-File
av-<kunde-slug>.md§ Storage referenzieren
Konventionen
Endpoint-Pattern
| Region | Endpoint |
|---|---|
| Falkenstein (DE) | https://fsn1.your-objectstorage.com |
| Nürnberg (DE) | https://nbg1.your-objectstorage.com |
| Helsinki (FI) | https://hel1.your-objectstorage.com |
Pfad-Stil
- Virtual-hosted-style ist Default (
https://<bucket>.<region>.your-objectstorage.com) - Path-style funktioniert (für Terraform-S3-Backend, AWS-SDK mit
use_path_style: true) - Empfehlung: virtual-hosted für App-Code, path-style für Tooling (Terraform, manuelle AWS-CLI)
Bucket-Layout
| Bucket-Typ | Top-Level-Prefixes | Erklärung |
|---|---|---|
<kunde>-data | walg/, pgdump/, app/ | WAL-G Continuous Archive, nightly pg_dump, App-spezifische Daten |
<kunde>-audit | llm/<yyyy>/<mm>/<dd>/<hh>.jsonl.gz.age | LLM-Audit-Logs stündlich, age-encrypted (D-PLAN-14) |
Was Hetzner Object Storage NICHT kann (vs AWS S3)
| Feature | Hetzner Status | Workaround |
|---|---|---|
| Replication (cross-region/cross-bucket) | ❌ | rclone-Sync als Cron, deferred bis 2. Industriekunde |
| Storage Classes (Glacier, IA) | ❌ — nur STANDARD | Lifecycle-Expiration statt Cold-Tier |
| Bucket Logging | ❌ | App-Side-Logging in Postgres audit_log |
| Bucket Website Hosting | ❌ | Cloudflare-Tunnel zur App, kein Static-Hosting auf Bucket |
| Object Tagging | ❌ | Metadaten in App-DB statt Bucket-Tags |
| Object-Lock nachträglich aktivieren | ❌ — nur bei Bucket-Erstellung | Test-Bucket vor Prod, neuer Bucket bei nachträglichem Bedarf |
| Cross-Region | ❌ — Bucket lebt in einer Region | rclone manuell für Off-Site-Copy |
Pricing (Stand Mai 2026)
- Base: 4,99 €/Monat — enthält 1 TB Storage + 1 TB Egress
- Excess Storage: ~5 €/TB/Monat
- Excess Egress: 1,00 €/TB Internet-Egress
- Internal Traffic (zu Hetzner Cloud Server in gleicher Region): kostenlos
- Limits: 100 TB pro Bucket, 50 Mio Objects pro Bucket
Quelle: Hetzner Object Storage Pricing
Object-Count-Risiko bei Audit-Logs
Pattern aus plan D-PLAN-7: hourly JSONL pro Kunde = 24 Objects/Tag = 8760 Objects/Jahr. Bei 7y-Retention = ~61k Objects pro Kunde — weit unter 50M-Limit.
Bei mehreren Kunden im gleichen Bucket (shared agentic-audit-Bucket): >100 Kunden würde Limit erreichen — dann pro Kunde eigenen Bucket. Aktuelle Konvention (1 Bucket pro Kunde-Project) hält das auseinander.
Cost-Tracking
Object-Storage-Kosten sind pro Project separat in Hetzner-Billing sichtbar. Cost-Alarm-Schwellen (siehe cost-alarme-pro-project) decken Object Storage mit ab.
Related
- _index — Capability-Dashboard
- projects — Project-Inventar
- buckets — Vergleichs-Pattern AWS-S3
- plan Unit 3 + D-PLAN-6/14 — Object-Storage-Setup in der MVP-Iteration
- llm-hosting-eu-optionen — strategische Grundlage Hetzner-Hosting