Mastodon und Hetzner Object Storage

Seit 2022 betreibe ich meine eigene Mastodon-Instanz auf einem Hetzner Cloud-Server. Um die Medieninhalte unabhängig vom Dateisystem des Servers zu halten, habe ich mich entschieden, den S3-kompatiblen Hetzner Object Storage als Objektspeicher zu nutzen. Dieser Artikel zeigt Dir, wie Du den Dienst einrichtest und welche Gedanken ich mir dazu gemacht habe.
Ausgangslage und Vorüberlegungen
Vor der Umstellung ist das Dateisystem meines Hetzner Cloud-Servers gut gefüllt:
df -kh /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 38G 33G 3.7G 90% /
Üblicherweise werden die Medieninhalte von Mastodon im Verzeichnis /opt/mastodon/public/system
gespeichert. Dort befinden sich Unterverzeichnisse für Accounts, Cache, Medienanhänge und Site-Uploads:
du -sh /opt/mastodon/public/system/*
440K /opt/mastodon/public/system/accounts
17G /opt/mastodon/public/system/cache
170M /opt/mastodon/public/system/media_attachments
208K /opt/mastodon/public/system/site_uploads
Die S3-API ist eine standardisierte Schnittstelle, die ursprünglich von Amazon Web Services (AWS) entwickelt wurde, um den Zugriff auf Objekte über HTTP-Anfragen zu ermöglichen. Inzwischen haben viele Cloud-Anbieter, darunter auch Hetzner, diese API implementiert, um eine einfache Integration in bestehende Lösungen zu ermöglichen. Mastodon unterstützt die S3-API, was bedeutet, dass Du den Hetzner Object Storage als Medien-Backend nutzen kannst.
Hetzner ist eine deutsche Firma mit Sitz in Gunzenhausen. Ein großer Vorteil von Hetzner ist die Speicherung der Daten in deutschen bzw. europäischen Rechenzentren, was höchste Datenschutzstandards garantiert. Zudem legt Hetzner Wert auf Nachhaltigkeit und betreibt seine Rechenzentren mit erneuerbaren Energien. Der Hetzner Object Storage ist derzeit in Falkenstein, Nürnberg und Helsinki verfügbar. Man kann bis zu 100 Buckets mit je bis zu 100 TB Speicher und bis zu 50.000.000 Objekten pro Bucket anlegen.
Die Preisstruktur von Hetzner ist besonders transparent und fair, gerade im Vergleich zu internationalen Wettbewerbern. Die Abrechnung des Dienstes erfolgt nutzungsbasiert. Da ich meine Mastodon-Instanz 24/7 betreibe, werden monatlich 4,99 EUR (zzgl. MwSt.) fällig. Darin enthalten sind 1 TB Speicherplatz und 1 TB ausgehender Traffic im Monat. Das genaue Abrechnungsmodell betrachtet den Speicherplatz in Terabyte-Stunden. Die Mindestobjektgröße für die Abrechnung sind 64 KB. Traffic für Uploads, innerhalb der Hetzner-EU-Rechenzentren und über die S3-API ist kostenlos.
Die Zielarchitektur sieht in etwa so aus:
Konfiguration des Buckets
Die Anlage eines Buckets erfolgt über die Hetzner Console. Dort wähle ich im Projekt den Reiter “Object Storage” und klicke auf “Bucket erstellen”.
Ich vergebe den Namen mastodon-abshoff-social
und wähle den Standort fsn1
(Falkenstein) aus. Die Sichtbarkeit setze ich auf Öffentlich (read-only)
, damit die Medieninhalte abgerufen werden können.
Anschließend können über den Menüpunkt “S3-Zugangsdaten” mit Access Key und Secret Key für das Projekt erstellt werden.
Die nachfolgenden Konfigurationsdateien enthalten Platzhalter (...
), die durch die tatsächlichen Zugangsdaten ersetzt werden müssen. Die Zugangsdaten sollten sicher aufbewahrt werden, da sie den Zugriff auf den Bucket ermöglichen.
Migration der vorhandenen Medieninhalte
Im ersten Schritt räume ich die vorhandenen Dateien auf. Dazu nutze ich das Admin-CLI-Tool tootctl
von Mastodon. Die nachfolgenden Befehle verwende ich in meinen täglichen Wartungsskripten teilweise mit einer anderen Zeitangabe.
tootctl media remove --days=0
tootctl media remove --prune-profiles --days=0
tootctl preview_cards remove --days=0
tootctl media remove-orphans
tootctl cache clear
Danach ist der Speicherplatzverbrauch deutlich reduziert:
du -sh /opt/mastodon/public/system/*
440K /opt/mastodon/public/system/accounts
1.5G /opt/mastodon/public/system/cache
166M /opt/mastodon/public/system/media_attachments
208K /opt/mastodon/public/system/site_uploads
Als nächstes kopiere ich die verbliebenen Medieninhalte in den Objektspeicher. Dazu können Tools wie MinIO Client mc
, S3cmd s3cmd
, Rclone rclone
oder die AWS CLI aws
verwendet werden. Ich habe mich für rclone
entschieden.
In der Datei .config/rclone/rclone.conf
habe ich einen Eintrag für hetzner-fsn1
wie folgt konfiguriert:
[hetzner-fsn1]
type = s3
provider = Other
access_key_id = ...
secret_access_key = ...
endpoint = fsn1.your-objectstorage.com
acl = public-read
region = fsn1
Mit folgendem Befehl kopiere ich die verbliebenen Medieninhalte in den Objektspeicher:
rclone copy /opt/mastodon/public/system/ hetzner-fsn1:mastodon-abshoff-social
Nach ein paar Minuten ist der Kopiervorgang abgeschlossen und das Bucket ist gefüllt:
Als nächstes habe ich Mastodon konfiguriert, sodass es den Objektspeicher für die Medieninhalte nutzt. Dazu habe ich die Datei /opt/mastodon/.env.production
angepasst:
S3_ENABLED=true
S3_ENDPOINT=https://fsn1.your-objectstorage.com
S3_BUCKET=mastodon-abshoff-social
S3_REGION=fsn1
S3_ALIAS_HOST=abshoff.social/system
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
Damit werden die Medieninhalte weiterhin unter der URL https://abshoff.social/system
verlinkt. Damit diese nicht mehr über das lokale Dateisystem, sondern über den Objektspeicher bereitgestellt werden, habe ich die Konfiguration des lokalen Nginx nginx.conf
angepasst:
location ~ ^/system/ {
limit_except GET {
deny all;
}
proxy_set_header Host mastodon-abshoff-social.fsn1.your-objectstorage.com;
proxy_set_header Connection '';
proxy_set_header Authorization '';
proxy_hide_header Set-Cookie;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_hide_header x-rgw-object-type;
proxy_hide_header x-amz-meta-mtime;
proxy_hide_header x-debug-bucket;
proxy_hide_header cache-control;
proxy_hide_header strict-transport-security;
proxy_hide_header x-content-type-options;
proxy_hide_header content-security-policy;
proxy_ignore_headers Set-Cookie;
proxy_intercept_errors off;
rewrite ^/system(.*) $1 break;
proxy_pass https://mastodon-abshoff-social.fsn1.your-objectstorage.com;
proxy_cache CACHE;
proxy_cache_valid 200 48h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
expires 1y;
add_header Cache-Control public;
add_header 'Access-Control-Allow-Origin' '*';
add_header X-Cache-Status $upstream_cache_status;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'none'; form-action 'none'";
}
Nach Neustart von Nginx und Mastodon ist die Migration abgeschlossen. Die Medieninhalte werden nun über den Objektspeicher bereitgestellt. Abschließend habe ich noch einmal die Medieninhalte mit rclone
in den Hetzner Object Storage kopiert, um sicherzustellen, dass alle Dateien übertragen wurden, und schließlich den lokalen Ordner archiviert:
rclone copy /opt/mastodon/public/system/ hetzner-fsn1:mastodon-abshoff-social
Backup des Buckets über die Synology DiskStation
Die Medieninhalte im Hetzner Object Storage sind durch die Replikation in mehreren Rechenzentren und die hohe Verfügbarkeit des Dienstes gut geschützt. Dennoch ist es ratsam, regelmäßige Backups der Daten zu erstellen. Dies kann entweder durch das Erstellen von Snapshots des Buckets oder durch das regelmäßige Herunterladen der Daten auf einen anderen Speicherort erfolgen.
Ich nutze dafür Cloud-Sync-Funktion meiner Synology DiskStation. Zunächst wähle ich dort den S3 Cloud Provider aus:
Dann gebe ich die Zugangsdaten für den Hetzner Object Storage ein:
Schließlich definiere ich in den Einstellungen, dass ich nur Dateien herunterladen und keinen bidirektionalen Sync durchführen möchte.
In den erweiterten Einstellungen habe ich den cache
-Ordner ausgeschlossen, da dieser nicht wichtig ist. Für die Backup-Strategie ist zu überlegen, ob diese “live” oder nur zu bestimmten Zeiten durchgeführt werden sollen.
Fazit
Die Migration von Mastodon zum Hetzner Object Storage war ein ziemlich reibungsloser Prozess. Die S3-kompatible API von Hetzner ermöglicht eine einfache Integration und bietet eine kostengünstige, skalierbare Lösung für die Speicherung von Medieninhalten. Die transparente Preisstruktur und die Einhaltung hoher Datenschutzstandards machen Hetzner zu einer attraktiven Wahl für die Nutzung im Fediverse.
Quellen und Links
Die vorangegangene Konfiguration und Migration habe ich mit Hilfe folgender Quellen durchgeführt:
Hetzner Object Storage:
- https://www.hetzner.com/de/storage/object-storage
- https://mastodon.hetzner.social/@hetzner/114816844710178488
- https://docs.hetzner.com/de/storage/object-storage
Migration zu S3:
Mastodon Dokumentation:
- https://docs.joinmastodon.org/admin/optional/object-storage/
- https://docs.joinmastodon.org/admin/optional/object-storage-proxy/
Tags: