Die Eine-Datei-Philosophie
PocketBase und Beszel behaupten dasselbe: maximale Funktionalitaet bei minimaler Betriebskomplexitaet. Ein Binary, ein Container, fertig. Dieser Report prueft die Behauptung — und rechnet sie gegen deinen tatsaechlichen Bestand auf maierzone.de durch.
1 · Die These in einem Satz
Der Aufwand, ein System zu betreiben, ist in den letzten zehn Jahren schneller gewachsen als der Aufwand, es zu schreiben — und eine Gegenbewegung nimmt sich heraus, diesen Betriebsaufwand radikal zu streichen, indem sie alle Infrastrukturbausteine in ein einziges ausfuehrbares Artefakt zusammenzieht.
Das ist keine neue Idee. Es ist die Rueckkehr des Monolithen — aber mit einem entscheidenden Unterschied zu den Monolithen von 2010: Diesmal ist auch die Datenbank mit drin. Und genau das ist der eigentliche Sprung, denn der Datenbankserver war jahrzehntelang der Grund, warum ein Deployment nie aus einem Ding bestehen konnte.
2 · Was da technisch wirklich steht
Ein Go-Backend, das eingebettetes SQLite mit Realtime-Subscriptions, Datei- und Benutzerverwaltung, einer Admin-Oberflaeche und einer REST-artigen API in einer Binaerdatei buendelt. Prebuilt-Executable herunterladen, ./pocketbase serve — das ist das komplette Setup.
Zwei Betriebsarten, und die zweite ist die interessantere:
- Standalone — laeuft as-is, erweiterbar ueber eine eingebaute JavaScript-VM.
- Als Go-Bibliothek — du importierst PocketBase in dein eigenes
main.go, registrierst eigene Routen und Hooks, und kompilierst wieder zu genau einer portablen Datei.
Statisch gelinkt mit CGO_ENABLED=0, weil der SQLite-Treiber reines Go ist. Deshalb keine libc-Abhaengigkeit, deshalb ein 15-MB-Scratch-Image statt eines 400-MB-JRE-Images.
Der Beweis, dass das Muster traegt. Beszel ist Server-Monitoring in Hub-und-Speiche-Topologie: Der Hub ist eine PocketBase-Anwendung mit React-Frontend, der Agent ein winziges Go-Binary je ueberwachtem Host.
Was Beszel dadurch geschenkt bekommt, ohne eine Zeile dafuer zu schreiben: Benutzerverwaltung, OAuth/OIDC-Login, automatische S3-Backups, Log-Ansicht, REST-API und Realtime-Updates im Dashboard. Der Anwendungscode kuemmert sich nur noch um Metriken.
Die Zeitreihen liegen als PocketBase-Collections vor — Rohdaten im Minutentakt plus vorverdichtete Stufen (10 min / 20 min / 2 h / 8 h). Das ist die SQLite-Antwort auf Prometheus-Retention: kein TSDB, nur Aggregationstabellen.
Agents sprechen ueber WebSocket, mit SSH als Rueckfallebene. Die SSH-Strecke ist bewusst kastriert: kein PTY, keine Kommandoausfuehrung. Kompromittierter Hub-Key bedeutet keine Shell auf den Agents.
3 · Warum das gerade jetzt zieht
Die Oekonomie ist simpel und unangenehm ehrlich: Ein verteilter Stack hat hohe Fixkosten und niedrige Grenzkosten. Ein Monolith genau umgekehrt. Bei Kubernetes zahlst du Wochen, bevor der erste Nutzer etwas sieht — dafuer kostet der zwanzigste Service kaum mehr als der zehnte. Bei einem Binary bist du in Minuten produktiv — dafuer wird jede zusaetzliche Dimension teurer.
Der ganze Trend ist letztlich die Beobachtung, dass die allermeisten Projekte den Kreuzungspunkt nie erreichen und trotzdem seit Jahren die Fixkosten bezahlen.
Schematisches Modell, keine Messreihe. Waagerecht: wachsende Anforderungen (Teams, Schreiblast, Verfuegbarkeitsziele). Senkrecht: Gesamtaufwand aus Bau plus Betrieb. Die Frage fuer jedes Projekt lautet nicht welche Kurve besser ist, sondern: Wo auf der Achse stehe ich realistisch — heute und in zwei Jahren?
Jeder Pfeil ist ein Ausfallpunkt, eine Zugangsdatei und eine Version, die zueinander passen muss.
DB · Auth · API · Realtime · Admin-UI · Backup
Backup ist eine Dateikopie. Rollback ist eine Dateikopie. Umzug auf einen anderen Server ist eine Dateikopie. Das ist der unterschaetzte Teil des Gewinns.
4 · Realitaetscheck — wo die Philosophie bricht
Der Trend wird ueberwiegend von Leuten beschrieben, die ihn gerade begeistert entdeckt haben. Fuenf Punkte, die in den Begeisterungstexten fehlen.
-
R-01 SQLite hat genau einen SchreiberWAL-Modus erlaubt beliebig viele parallele Leser, aber Schreibvorgaenge werden serialisiert. Fuer Lese-dominierte Anwendungen ist das voellig unkritisch. Sobald du echte Schreiblast hast — viele Nutzer, die gleichzeitig Daten aendern — ist es eine harte Wand, und zwar eine, gegen die du erst im Betrieb faehrst. Das ist kein Fehler, das ist eine Designentscheidung. Aber sie ist nicht verhandelbar.
-
R-02 Vier Jahre, 263 Releases, immer noch vor 1.0Das Projekt sagt selbst, dass volle Rueckwaertskompatibilitaet vor 1.0 nicht garantiert ist. Fuer ein privates Projekt ist das verkraftbar. Aber es heisst: Du kaufst dir eine wiederkehrende Migrationspflicht ein, und du kaufst sie bei einem Projekt, das im Wesentlichen von einer Person getragen wird. Rechne das in die Betriebskosten ein, die du gerade sparen wolltest.
-
R-03 Fuer dich ist es ein SprachbruchDas ist dein spezifischer Punkt. PocketBase erweiterst du in Go oder in der eingebetteten JavaScript-VM — nicht in Java. Deine gesamte Kompetenz in Spring, deine Testroutinen, deine Bibliotheksvertrautheit gelten dort nicht. Bei einem CRUD-Backend, das du ohnehin kaum anfasst, ist das egal. Sobald nennenswerte Fachlogik hineinwandert, hast du dir eine zweite Codebasis in einer Zweitsprache gebaut — und damit exakt die Komplexitaet zurueckgekauft, die du streichen wolltest.
-
R-04 Keine Vektorsuche, keine Erweiterungen ohne SonderbauDer SQLite-Treiber ist reines Go — das ist der Grund fuer die statische Verlinkung, und zugleich der Grund, warum C-Extensions nicht einfach dazugeladen werden. Fuer Matroshka ist damit entschieden: pgvector hat keine bequeme Entsprechung. Wer semantische Suche braucht, bleibt bei PostgreSQL.
-
R-05 Eine Datei heisst nicht wenig KopplungDer gefaehrlichste Denkfehler in diesem Trend. Microservices machen Kopplung sichtbar, indem sie sie an Netzwerkgrenzen zwingen. Ein Binary macht Kopplung unsichtbar — sie ist weiterhin da, nur nicht mehr im Betriebsdiagramm. Der Trend loest ein Betriebsproblem, kein Architekturproblem. Wer beides verwechselt, baut in zwei Jahren einen grossen Ball Schlamm und wundert sich, warum die Vereinfachung nichts gebracht hat.
5 · Wieviel laeuft eigentlich dauerhaft?
Anzahl dauerhaft laufender Prozesse je Deployment. Die geplanten Staende (Matroshka, Wiki) sind aus deinen Architekturentscheidungen abgeleitet, MZP ist geschaetzt. Die Zahl selbst ist nicht das Problem — das Problem ist, dass jeder dieser Prozesse Speicher belegt, ein Update braucht und dir bei einem Ausfall um 3 Uhr nachts erklaert werden will.
6 · Anwendung auf deinen Bestand
Erwarteter Nutzen eines gemeinsamen PocketBase-Backends, 0 bis 10. Bewertet wird nicht, ob es technisch ginge — es ginge fast ueberall — sondern ob es dir tatsaechlich Arbeit abnimmt.
| Projekt | Was PocketBase uebernehmen wuerde | Verdikt |
|---|---|---|
| whiteboard | Realtime-Subscriptions fuer kollaborative Zeichenflaechen, Persistenz der Boards, Bild-Uploads als File-Fields | PILOT |
| calendar | Benutzerverwaltung, Termin-Records, Tags, Freigaben zwischen Familienmitgliedern, iCal-Import ueber einen Hook | STARK |
| words | Wortlisten, Lernstaende, Fortschritt je Nutzer — reines CRUD, exakt der Sweet Spot | STARK |
| excel | Dateiablage fuer Arbeitsmappen plus Metadaten-Collection; Versionierung muesstest du selbst modellieren | GUT |
| game / game3d | Wenig — Game of Life braucht keinen Zustand. Hoechstens Highscores, geteilte Seeds, gespeicherte Muster | OPTIONAL |
| mzone-publisher | Nichts Sinnvolles. MZP ist bereits eine fertige Spring-Boot-Anwendung mit eigener Domaene, MCP-Schnittstelle und Versionierung. Ein Umbau waere reine Zerstoerung von Wert | NEIN |
| Matroshka | Nichts. pgvector, Anthropic-Java-SDK, Cron-Schleifen, Schichtenlogik in Java — hier ist der verteilte Stack begruendet | NEIN |
Der eine Zug, der sich sofort rechnet
Am 31. Juli ist dir der mzone-publisher-Container mit OutOfMemoryError: Metaspace weggekippt. Gemerkt hast du es an der Fehlermeldung — also im Nachhinein.
Beszel ist genau die Antwort darauf, und zwar zu einem Preis, der die Entscheidung trivial macht: ein Hub-Container auf dem VPS, ein Agent-Binary, Alarme bei Speicher- und Plattenschwellen, Container-Statistiken je Docker-Dienst. Kein Prometheus, kein Grafana, keine Exporter, keine Alertmanager-YAML. Das ist die einzige Empfehlung in diesem Report, bei der ich keinen Gegeneinwand habe.
Nebeneffekt: Du siehst danach zum ersten Mal, wie viel RAM deine sieben Deployments zusammen tatsaechlich brauchen — und das ist genau die Zahl, die du fuer die Matroshka-Entscheidung unten brauchst.
7 · Der ehrlichere Transfer: Eine-Datei in Java
Der eigentliche Wert dieses Trends liegt fuer dich nicht darin, PocketBase zu benutzen. Er liegt in der Frage, die PocketBase stellt: Warum laeuft das eigentlich in fuenf Prozessen? Diese Frage kannst du in deinem eigenen Stack beantworten.
Ein Spring-Boot-Fat-JAR ist bereits ein Ein-Datei-Artefakt. Der Unterschied zu PocketBase ist nicht die Anwendung — es ist alles, was du daneben stellst.
Fuer kleine Anwendungen: sqlite-jdbc mit JPA und WAL-Modus. Ein Container weniger, ein Passwort weniger, Backup wird zur Dateikopie. Bei Lese-dominierter Last kostet es dich praktisch nichts.
Fuer Matroshka als Ein-Nutzer-System ist Keycloak plus dessen eigene Datenbank ein Identity-Provider im Unternehmensmassstab fuer genau einen Menschen. Das sind zwei Prozesse und mehrere hundert MB RAM fuer eine Anmeldemaske. Spring Security mit einem einzelnen Nutzer aus der Konfiguration leistet dasselbe.
Gegenargument, das du selbst pruefen musst: Keycloak laeuft bereits fuer auth.maierzone.de und wird vom Wiki mitbenutzt. Wenn es ohnehin steht, ist der Grenzpreis fuer Matroshka fast null. Dann waere Streichen falsch.
Der direkteste Java-Weg zum echten Binary: kein JVM-Start, kein Metaspace, drastisch weniger Grundspeicher. Preis: laengere Builds und Reflection-Konfiguration. Fuer MZP waere es die eigentliche Antwort auf den Metaspace-Absturz — nicht ein hoeheres Limit.
8 · Empfohlene Reihenfolge
-
S-01 Beszel deployen — diese WocheEin Container, ein Agent, ein Nginx-Block auf einer neuen Subdomain. Kosten: unter einer Stunde. Nutzen: du weisst ab dann, was auf deinem VPS wirklich passiert, statt es aus Stacktraces zu rekonstruieren. Nebenbei hast du ein reales, laufendes Beispiel der Philosophie zum Anfassen.
-
S-02 Eine PocketBase-Instanz als gemeinsames Backend erprobenNicht sieben Instanzen — eine, mit einer Collection je Anwendung. Fang mit whiteboard an, weil dort die Realtime-Subscriptions den groessten Effekt haben und du diesen Teil sonst selbst bauen muesstest. Wenn es traegt, ziehen calendar und words nach. Wenn nicht, hast du eine Datei geloescht und nichts verloren.
-
S-03 Den Matroshka-Compose-Stack durchrechnen — nicht umbauenApp, PostgreSQL, Keycloak, SearXNG, Ollama. Frage je Dienst: Was genau bricht, wenn er weg ist? Bei PostgreSQL und Ollama ist die Antwort klar. Bei Keycloak haengt sie daran, ob er ohnehin fuer andere Dienste laeuft. Das Ergebnis ist eine bewusste Entscheidung — und die ist mehr wert als jede Streichung aus Prinzip.
-
S-04 MZP: Native Image evaluieren, Architektur unangetastet lassenDer Metaspace-Absturz war ein Symptom, kein Architekturfehler. Falls er wiederkehrt, ist ein Classloader-Leak beim Template-Rendering die wahrscheinlichere Ursache als zu wenig Speicher — und Native Image wuerde die Klasse von Problem strukturell entfernen.
9 · Die Fragen, die du dir stellen solltest
- Ist deine Komplexitaet Betriebs- oder Fachkomplexitaet? Der Trend loest nur die erste. Wenn dein Schmerz aus verschachtelter Fachlogik kommt, aendert ein Binary daran nichts.
- Wie viele deiner Dienste haben je mehr als einen gleichzeitigen Schreiber gesehen? Wenn die ehrliche Antwort null ist, zahlst du fuer PostgreSQL eine Versicherung gegen ein Risiko, das nicht existiert.
- Waere ein zweisprachiger Stack ein Fortschritt oder eine neue Schuld? Go daneben zu haben ist genau so lange billig, wie du nichts Ernsthaftes darin schreibst.
- Was ist der eigentliche Zweck von Matroshka? Wenn es auch Portfolio und Papier-Grundlage fuer eine Bewerbung ist, ist eine reichere Architektur womoeglich ein Merkmal und kein Fehler. Vereinfachung um ihrer selbst willen kann hier gegen dein Ziel arbeiten.
PocketBase ist kein Architekturmuster, das man uebernimmt — es ist eine Frage, die man sich stellen laesst. Die Frage lautet: Was von dem, was hier laeuft, wuerde ich nochmal aufsetzen, wenn ich heute anfinge?
Fuer deine sechs kleinen Frontend-Projekte ist die Antwort wahrscheinlich: viel weniger als jetzt. Fuer Matroshka ist sie: fast alles, ausser vielleicht Keycloak. Und das ist ein gutes Ergebnis — es heisst, dass deine Architekturentscheidungen dort begruendet waren.