← zurück zur Startseite
root@souverainete:~$ cat etude-de-cas/grav.md
fallstudie — stack: grav cms

Eine wiederverwendbare Basis, um mehrere Grav-Websites bereitzustellen und zu betreiben

Statt die Installation einer einzelnen Website zu automatisieren, eine Architektur, die Runtime, Anwendungen, persistente Daten und Deployment-Mechanismus trennt — konzipiert, um den Lebenszyklus mehrerer Grav-Websites zu beherrschen, ohne deren Betrieb zu duplizieren.

Art des ProjektsWiederverwendbare Deployment-Basis
AusgangspunktInterne Dokumentationswebsite auf Grav-Basis
Anfängliche VorgabeInhalte bei Redeployments erhalten
StackLinux · Ansible · Docker · Grav · Git
// kontext

Das Problem begann bei der Persistenz

Der erste Bedarf war recht einfach: das Deployment einer als interne Dokumentation genutzten Grav-Website automatisieren.

Doch diese Website sollte sich nach dem Deployment weiterentwickeln. Seiten würden über die Admin-Oberfläche bearbeitet, Bilder hinzugefügt, Konten angelegt.

Ein erneutes Deployment der Anwendung durfte die Website deshalb niemals in ihren Ausgangszustand zurückversetzen und die im Betrieb erzeugten Daten zerstören.

Eine erste Grenze wurde sichtbar:

Die Anwendung muss ersetzbar sein. Die Nutzerdaten müssen überleben.

Die persistenten Inhalte wurden daher vom Lebenszyklus des Containers getrennt.

Dann brauchten weitere Projekte Grav-Websites. Die Frage lautete nicht mehr: Wie stelle ich diese Website bereit? sondern:

Wie lässt sich ein Mechanismus schaffen, mit dem sich mehrere Grav-Websites bereitstellen und betreiben lassen, ohne die Betriebslogik zu duplizieren?

In diesem Moment wurde aus einem Deployment-Problem ein Architekturproblem.

// anforderungen

Was in Einklang zu bringen war

Persistenz

Im Betrieb erzeugte Inhalte müssen das Ersetzen eines Containers, ein Redeployment und einen Versionswechsel überstehen.

Wiederverwendbarkeit

Die gemeinsame Mechanik darf nicht für jedes neue Projekt kopiert und angepasst werden.

Wartbarkeit

Runtime, Anwendung, Daten und Deployment entwickeln sich weder im gleichen Takt noch aus denselben Gründen. Ihre Trennung sollte diese Lebenszyklen widerspiegeln.

Reversibilität

Die Rückkehr zu einer vorherigen Version sollte so weit wie möglich denselben Mechanismus nutzen wie ein normales Deployment.

Sicherheit

Secrets und sensible Konfiguration bleiben außerhalb der Anwendungs-Images und des versionierten Codes.

// architektur

Unterschiedliche Lebenszyklen, getrennte Zuständigkeiten

Die Analyse des ersten Deployments und die Ankunft neuer Projekte machten vier unterschiedliche Bereiche sichtbar: Runtime, Anwendung / Website, persistente Daten und Deployment-Mechanismus. Sie nur deshalb zusammenzufassen, weil sie derselben Website dienen, hätte eine unnötige Kopplung geschaffen. Die Architektur zielt daher darauf ab, diese Grenzen explizit zu machen.

// grav-runtime (gemeinsame Basis) → unabhängige Anwendungen → ansible-role-grav-site (gemeinsames Deployment) → Instanzen → vom Container entkoppelte Daten
Eine gemeinsame Runtime

grav-runtime stellt das gemeinsame technische Fundament bereit: Grav, PHP, Nginx und den von den Anwendungen erwarteten Vertrag. Sie kennt kein einzelnes Fachprojekt.

Unabhängige Anwendungen

projet-gites, projet-lavallee-website und künftige Websites fügen nur das hinzu, was ihnen eigen ist: Theme, Plugins, Anwendungskonfiguration und Ausgangsinhalte. Jede Anwendung bleibt unabhängig versioniert.

Ein gemeinsamer Deployment-Mechanismus

ansible-role-grav-site zentralisiert die gemeinsame Mechanik: Vorbereitung der Instanz, persistente Volumes, Konfiguration, Secrets, Start, Health-Checks, Updates und Rollback. Die Rolle bleibt auf eine Instanz pro Aufruf ausgerichtet.

Daten außerhalb des Container-Lebenszyklus

Seiten, Bilder, Konten und andere persistente Daten leben unabhängig vom Anwendungs-Image. Eine neue Version kann die Anwendung daher ersetzen, ohne automatisch ihren Produktionszustand zurückzusetzen.

// umsetzung

Von der Installation zum Lebenszyklus

01

Erster Bedarf: Daten persistent machen

Das erste Deployment ermöglichte es, eine grundlegende Regel zu formalisieren: rekonstruierbare Elemente gehören zur Anwendung; im Betrieb erzeugte Daten müssen außerhalb des Containers leben.

02

Extraktion einer gemeinsamen Runtime

Grav, PHP, Nginx und die gemeinsamen Abhängigkeiten wurden in grav-runtime isoliert. Anwendungsprojekte müssen diese technische Schicht dadurch nicht mehr selbst aufbauen.

03

Zentralisierung des Deployments

Die Betriebsmechanik wurde in ansible-role-grav-site zusammengefasst: Volumes, Secrets, Konfiguration, Health-Checks, bereitgestellte Version, Update und Rollback.

04

Übergang zu mehreren Anwendungen

projet-gites, dann lavallee.tech, ermöglichten es, das Modell an mehreren realen Anwendungen zu prüfen. Die zweite Website deckte insbesondere Annahmen auf, die noch an das erste Projekt gebunden waren — Namen, Pfade oder Instanzeigenschaften — und löste deren Verallgemeinerung aus.

// lebenszyklus

Installation ist nur der erste Schritt

Eine Anwendung wird nur einmal installiert. Danach muss sie über Jahre betrieben werden können. Das gesuchte Modell lautet daher nicht mehr:

install

sondern:

deploy → update → rollback → migrate

Dieser Unterschied prägt die Architektur. Die Runtime ist versioniert. Jede Anwendung ist versioniert. Daten bestehen unabhängig fort. Der Deployment-Mechanismus setzt den gewünschten Zustand um.

// rollback

Rollback bleibt ein Deployment

Rollback ist nicht als eigenständiges Notfallverfahren konzipiert. Verursacht eine neue Version ein Problem, wird einfach eine zuvor als stabil bekannte Version wieder zur gewünschten Version.

version 1.3.2
      │
      ▼
 deploy 1.4.0
      │
  problem
      │
      ▼
 ziel = 1.3.2
      │
      ▼
derselbe deployment-mechanismus

Das begrenzt Sonderverfahren genau auf den Moment, in dem sie am riskantesten wären: während eines Vorfalls.

// ergebnis

Was diese Architektur verändert

Die Deployment-Logik ist zentralisiert, statt in jedes Projekt hineinkopiert zu werden. Jede Website behält ihre eigenen Inhalte, ihre Konfiguration und ihren Versionierungszyklus — und das Ersetzen einer Anwendung bedeutet nie das Ersetzen ihres persistenten Zustands.

1gemeinsame Runtime, unabhängig von den Websites gebaut und gepflegt
1Deployment-Mechanismus, statt pro Projekt kopiert zu werden
2unabhängige Anwendungen, auf derselben Basis bereitgestellt

Die erste Website hat einen Bedarf gelöst. Die zweite hat begonnen, die Architektur zu testen. Die nächsten müssen dieselbe Basis wiederverwenden können, ohne die Betriebslogik zu vervielfachen.

// beweis

Die zweite Website ist der eigentliche Test

Es ist leicht, eine Architektur als „wiederverwendbar“ zu bezeichnen, solange sie erst einem einzigen Projekt dient. Der zweite Nutzer deckt die Annahmen auf, die in Wirklichkeit spezifisch für das erste waren.

lavallee.tech ist inzwischen selbst auf dieser Architektur bereitgestellt. Ihre Ankunft ermöglichte es, die letzten Instanzparameter zu identifizieren, die verallgemeinert werden mussten, damit die Deployment-Rolle eine atomare, wiederverwendbare Komponente bleibt.

Der nächste Schritt besteht darin, denselben Mechanismus für eine neue technische Dokumentationswebsite zu nutzen. Wiederverwendbarkeit wird daher nicht als deklarierte Eigenschaft betrachtet.

Sie muss durch neue Nutzer bestätigt werden.

Neue technische Dokumentationswebsite in Vorbereitung

Dieselbe Basis — grav-runtime + ansible-role-grav-site — wird unverändert für diesen neuen Nutzer wiederverwendet, der einzig wirkliche Beweis dafür, dass eine Architektur wiederverwendbar ist.

// souveränität

Warum diese Architektur auch zur Beherrschung des Systems beiträgt

Der Einsatz von Open-Source-Software ist nur ein Teil des Problems. Eine Infrastruktur bleibt schwer zu beherrschen, wenn ihr Deployment von manuellen Eingriffen abhängt, ihre Daten mit der Anwendung vermischt sind oder niemand genau weiß, welche Version in Produktion läuft.

Diese Architektur zielt daher darauf ab, Folgendes explizit zu machen:

  • die verwendeten Komponenten;
  • die bereitgestellten Versionen;
  • die zu erhaltenden Daten;
  • die Zuständigkeiten jeder Schicht;
  • den Mechanismus, um eine Instanz wiederherzustellen.
Open Source ist ein Mittel. Die Beherrschung des Systems ist das Ziel.
// grenzen

Was die Basis nicht zu leisten versucht

Inhaltserstellung und redaktionelles Design bleiben Sache jeder einzelnen Anwendung.

Die Deployment-Rolle verwaltet weder DNS noch Reverse Proxy noch TLS-Zertifikate. Diese Zuständigkeiten liegen bei der gemeinsamen Infrastruktur.

Backups bleiben notwendig. Grav vermeidet den Betrieb eines zusätzlichen Datenbankdienstes, aber die persistenten Dateien sind Produktionsdaten und müssen gesichert werden.

Die Deployment-Rolle verwaltet eine Instanz pro Aufruf. Die Orchestrierung mehrerer Websites wird bewusst auf einer höheren Ebene behandelt.

Anwendungen mit komplexen Fachfunktionen, hohem Traffic oder fortgeschrittenen Datenmodellen können außerhalb des natürlichen Anwendungsbereichs eines Flat-File-CMS wie Grav liegen.

// komponenten

Die Basis und ihre Anwendungen

grav-runtime
Gemeinsame Runtime. Versioniertes Basis-Image, das Grav, PHP, Nginx und den gemeinsamen Runtime-Vertrag bereitstellt.
Auf GitHub ansehen →
ansible-role-grav-site
Deployment-Mechanismus. Ansible-Rolle, zuständig für den Lebenszyklus einer kompatiblen Grav-Instanz.
Auf GitHub ansehen →
projet-gites
Anwendung. Erste Fachwebsite, die die gemeinsame Basis nutzt.
Auf GitHub ansehen →
projet-lavallee-website
Anwendung. Zweite reale Website, die dieselbe Architektur nutzt — diejenige, die Sie gerade betrachten.
Auf GitHub ansehen →
// weiterführend

Warum diese Architektur?

Diese Trennung entstand nicht aus einem theoretischen Entwurf. Sie ist das Ergebnis der Entwicklung eines konkreten Bedarfs: die Daten einer ersten Website zu erhalten und dann zu verstehen, wie mehrere Anwendungen betrieben werden können, ohne ihre Infrastruktur zu duplizieren.

Artikel lesen: Von der Bereitstellung einer Website zur wiederverwendbaren Deployment-Plattform →

Ein Linux-Dienst, den es reproduzierbar und wartbar zu machen gilt?

Ein automatisiertes Deployment ist nur ein Teil des Problems. Die eigentliche Frage ist, wie das System aktualisiert, diagnostiziert, gesichert, wiederhergestellt und langfristig weitergegeben wird.

Lassen Sie uns zuerst über Ihre Rahmenbedingungen sprechen →