Funktionen / Erweitern

Drei Speicher-Backends

Dateien, SQLite oder Postgres — dieselbe API, dieselben Schemas, dieselbe Testsuite. Du wählst nach Betrieb, nicht nach Funktion, und wechselst später mit verifizierter Migration in beide Richtungen.

Wo dein Content liegt, ist eine Betriebsfrage: eine Instanz oder mehrere, Content im Git-Repo oder in einer Datenbank. RustyCMS macht daraus keine Produktfrage: Drei Backends stehen hinter derselben REST-API, denselben Schemas und derselben Konformanzsuite. Und die Entscheidung ist nicht endgültig.

Dateien: der Default, diffbar in Git

<content_dir>/<env>/<collection>/<slug>.json5

Ein Eintrag, eine Datei. git log sagt, wer was wann geändert hat, ein Diff im Pull-Request zeigt eine Textänderung, rsync schiebt den Baum auf den Server. Kein Dienst, kein Backup außer dem Repo. Writes sind atomar — Temp-Datei, fsync, rename.

Die Grenze ist real: eine Liste mit Filter und Sortierung liest die ganze Collection. Bis etwa 1000 Einträge je Collection ist das billiger als ein Datenbank-Roundtrip, bei 10 000 kostet dieselbe Liste 1,4 s statt 2 ms. Und zwei Prozesse auf demselben Verzeichnis überschreiben einander.

SQLite: eine Instanz, viele Einträge

Eine Datenbankdatei je Space. Filter, Sortierung und Fenster laufen als SQL statt als Scan, ohne dass jemand einen Datenbankserver betreibt. Der Preis: der Content ist binär — kein Diff, kein Review im PR.

Postgres: mehrere Instanzen

Eine Datenbank für alle Spaces, gebaut für zwei Container hinter einem Load-Balancer, Blue/Green, Managed-Hoster. Jeder Write meldet sich per LISTEN/NOTIFY an alle Instanzen, die ihren Cache verwerfen. Hintergrundjobs nehmen je Tick eine Sperre in der Datenbank, damit nur eine Instanz arbeitet. Edit-Locks gelten instanzübergreifend.

Dazu kommt, was nur eine Datenbank kann: Filter, Facetten und Referenz-Joins laufen als SQL — 50 Treffer mit einem Referenzfeld kosten 2 Anweisungen statt 51. index: true im Schema legt Sortier-Indizes an: 100 000 Zeilen sortiert mit Fenster, 17,6 → 0,74 ms. Lese-Views öffnen den Content für SQL- und BI-Tools. Volltext läuft als tsvector in derselben Transaktion wie der Eintrag. Beim Schreiben ist Postgres etwa 15-mal schneller als der Dateimodus.

Wechseln, mit Nachweis

# ohne --apply: Dry-run, nichts wird geschrieben
store-migrate --from file --to postgres --content-dir ./content \
  --database-url postgres://… --apply

Nach dem Kopieren liest das Werkzeug das Ziel zurück und vergleicht je Collection die Anzahl und je Eintrag einen sha256 über kanonisches JSON. Weicht etwas ab, bricht der Lauf ab, der Modus bleibt wie er war. --to file geht genauso — ein Archiv, das in fünf Jahren ohne Postgres lesbar ist. Der Modus ist in _config/store.json5 festgeschrieben; ein Start mit widersprechender Konfiguration bricht ab, statt still einen leeren Store hochzufahren.

Ehrlich: welchen nehmen

Der Dateimodus bleibt die Empfehlung. Mit eingeschaltetem Antwort-Cache sind alle drei auf der Leseseite messbar gleich — Postgres nimmst du für mehrere Instanzen oder SQL-Zugriff, nicht für Tempo. Und es ist ein Dokumentenmodell: ein Eintrag je Zeile, keine Tabelle je Collection, keine Fremdschlüssel in der Datenbank. Genau das ist die Bedingung dafür, dass der Rückweg in Dateien existiert.

Willst du das an deinem Projekt sehen?

Sag kurz, was du vorhast. Ich zeige die Admin-UI an einer echten Installation und sage ehrlich, ob es passt.

Früher Zugang anfragen