Featured image of post Reaktive lokale Dienste mit systemd, UNIX-Sockets und rootlosen Containern

Reaktive lokale Dienste mit systemd, UNIX-Sockets und rootlosen Containern

Ein informelles Referenzdokument zur Beschreibung eines Betriebsmusters für bedarfsorientierte, rootlose lokale Dienste mit systemd-Socket-Aktivierung.

Status: Informelles Referenzdokument / Pattern-Beschreibung
Zielgruppe: Linux-Administratoren, DevOps-/Platform-Engineers, systemd- und Podman-Anwender
Beispiel-Implementierung: Reactive-PlantUML auf GitHub

Motivation

Moderne Entwickler- und Administrationsumgebungen benötigen zunehmend lokale Dienste, die:

  • reproduzierbar konfiguriert sind,
  • keine permanent laufenden Hintergrundprozesse erfordern,
  • ohne Root-Rechte betrieben werden können,
  • und dennoch sauber in bestehende Systemmechanismen integriert sind.

Typische Beispiele sind lokale Vorschau‑Server, Dokumentationsdienste oder Hilfsdienste für IDEs.

Reactive-PlantUML entstand aus der Beobachtung, dass systemd, UNIX-Domain-Sockets und rootlose Container bereits alle notwendigen Bausteine bereitstellen, um solche Dienste reaktiv und bedarfsorientiert zu betreiben – ohne zusätzliche Infrastruktur oder Spezialframeworks.

Dieses Dokument beschreibt das daraus abgeleitete Betriebsmuster, nicht die konkrete PlantUML-Implementierung.


Grundprinzipien des Musters

Das hier beschriebene Muster basiert auf folgenden Invarianten:

  1. Rootless by default Alle Komponenten laufen als systemd user services.

  2. Socket-Aktivierung statt Daemons Dienste starten ausschließlich bei tatsächlicher Nutzung.

  3. Explizite Port-Verantwortung Die Zuordnung von TCP-Ports erfolgt bewusst durch den Benutzer.

  4. Keine internen TCP-Ports Interne Kommunikation erfolgt ausschließlich über UNIX-Domain-Sockets.

  5. Automatisches Idle-Shutdown Dienste beenden sich nach Inaktivität selbstständig.

  6. Reproduzierbarkeit vor Magie Alle Abhängigkeiten und Artefakte sind versioniert und überprüfbar.


Architekturüberblick

Der Datenfluss folgt einem strikt linearen Modell:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Client (Browser, IDE, CLI)
        │ TCP (lokaler, benutzerdefinierter Port)
systemd .socket (User-Unit)
systemd-socket-proxyd
        │ UNIX-Domain-Socket (%t/plantuml/<port>.sock)
rootloser Podman-Container
Applikation (z. B. PlantUML HTTP-Server)

Wesentliche Beobachtung:

Kein Bestandteil kennt mehr Kontext als notwendig.


Rolle der einzelnen Komponenten

systemd Socket Units (User)

  • Definieren ausschließlich den extern sichtbaren TCP-Port
  • Starten keinerlei Logik
  • Der Instanzname entspricht direkt dem Port (plantuml@8080.socket)

Dies erzwingt eine explizite, konfliktfreie Portwahl durch den Benutzer.


systemd-socket-proxyd

  • Übernimmt die Brückenfunktion zwischen TCP und UNIX-Socket
  • Wartet implizit auf die Verfügbarkeit des Ziel-Sockets
  • Beendet sich automatisch nach Inaktivität (--exit-idle-time)

Wichtig:

systemd-socket-proxyd ist zustandslos und enthält keinerlei Anwendungslogik.


Podman-Container (Quadlet)

Der Container:

  • läuft rootlos
  • besitzt keinen exponierten TCP-Port
  • erzeugt und verwaltet ausschließlich einen UNIX-Domain-Socket

Der Socket wird über ein RuntimeDirectory bereitgestellt und per Volume in den Container gemountet.


Interne Socket-Brücke (socat)

Innerhalb des Containers:

  • stellt die Applikation lokal einen TCP-Port bereit
  • socat bridged diesen Port zu einem UNIX-Socket

Dieses Detail ist austauschbar und kein Bestandteil des Musters – entscheidend ist lediglich, dass:

die Container-Grenze ausschließlich über einen UNIX-Socket überschritten wird.


Health Checks und Zustandsmodell

Health Checks erfolgen:

  • über den UNIX-Socket
  • ohne Nutzung externer Ports
  • sowohl während des Starts als auch im laufenden Betrieb

Der Container meldet seine Bereitschaft explizit an systemd (Notify=healthy).

Damit entsteht ein klares Zustandsmodell:

  • Socket offen → Anfrage möglich
  • Container healthy → Dienst verfügbar
  • Idle → automatisches Herunterfahren

Installation und Betrieb

Das Muster ist distributionsneutral, lässt sich aber besonders gut über Debian-Pakete ausrollen:

  • systemd-User-Units
  • Podman-Quadlets
  • Container-Build-Dateien

Nach Installation ist keine Aktivität erforderlich, bis der Benutzer bewusst einen Socket aktiviert:

1
systemctl --user enable --now plantuml@8080.socket

Abgrenzung und bewusste Nicht-Ziele

Dieses Muster versucht ausdrücklich nicht:

  • klassische Service-Orchestrierung zu ersetzen
  • Netzwerk-Namensräume zu abstrahieren
  • bestehende Init-Systeme zu umgehen
  • neue Sicherheitsmodelle einzuführen

Es nutzt ausschließlich:

  • bestehende systemd-Mechanismen
  • etablierte UNIX-Prinzipien
  • klar definierte Verantwortlichkeiten

Übertragbarkeit des Musters

Obwohl Reactive-PlantUML der konkrete Anwendungsfall ist, eignet sich das Muster u. a. für:

  • lokale Preview-Server
  • Dokumentationsdienste
  • Entwicklungs-Backends
  • Hilfsdienste für IDEs
  • kurzlebige Werkzeuge mit Netzwerkbedarf

Die konkrete Applikation ist austauschbar.


Fazit

Reactive-PlantUML zeigt kein neues Werkzeug, sondern ein ruhiges Zusammenspiel bestehender Mechanismen.

Das Muster ist:

  • transparent
  • reproduzierbar
  • wartbar
  • und bewusst unspektakulär

Oder anders formuliert:

Es passiert nur genau das, was passieren muss – und nichts darüber hinaus.

Erstellt mit Hugo
Theme Stack gestaltet von Jimmy