Wer aus moderner PHP-Entwicklung kommt, hat bestimmte Erwartungen. Ein Projekt hat eine composer.json. Der vendor/-Ordner ist in .gitignore. Nach einem git clone folgt composer install – erst dann läuft etwas. Das ist der Standard, den Composer seit über zehn Jahren etabliert hat.
Bei LimeSurvey funktioniert das anders.
Der erste Hinweis
Eine lokale LimeSurvey-Installation beginnt typischerweise so:
git clone https://github.com/LimeSurvey/LimeSurvey.git
Danach folgt der webbasierte Installer im Browser – Datenbankverbindung einrichten, Tabellen anlegen, Admin-Account erstellen. Fertig. Ein composer install ist zu keinem Zeitpunkt nötig.
In einem modernen PHP-Projekt wäre das unmöglich. Ohne composer install fehlt der vendor/-Ordner, Autoloading funktioniert nicht, keine einzige Abhängigkeit ist verfügbar. Bei LimeSurvey dagegen ist der vendor/-Ordner bereits im Repository eingecheckt – PHP-Abhängigkeiten inklusive. Das gilt auch für node_modules: JavaScript-Abhängigkeiten ebenfalls eingecheckt, npm install ebenfalls nicht nötig. Der Checkout ist in jeder Hinsicht direkt ausführbar.
Das ist keine Kleinigkeit. Es ist eine fundamentale architektonische Entscheidung, die den gesamten Umgang mit dem System prägt.
Was das bedeutet
LimeSurvey verhält sich nicht wie eine Composer-first-Anwendung. Es verhält sich wie eine Distribution: ein vollständiges, lauffähiges Paket, das ausgeliefert wird – nicht zur Laufzeit zusammengesetzt. Composer ist intern im Einsatz, die CI nutzt ihn, das Core-Team verwaltet darüber seine Abhängigkeiten. Für den Betreiber ist Composer kein Installationswerkzeug.
Der Unterschied zwischen diesen beiden Modellen ist erheblich. In einem Composer-first-Projekt ist composer.lock die maßgebliche Quelle der Wahrheit für den Zustand der Abhängigkeiten. In LimeSurvey ist der eingecheckte vendor/-Ordner der faktische Zustand – composer.lock beschreibt, wie dieser Zustand einmal erzeugt wurde, nicht wie er in jeder Umgebung reproduziert werden soll.
Warum composer install trotzdem funktioniert – und manchmal nicht
In einer sauberen CI-Umgebung läuft composer install problemlos: frischer Checkout, definierte PHP-Version, keine Altlasten. Das ist genau der Kontext, für den dieser Workflow gedacht ist.
In einer bestehenden Installation sieht es anders aus. Plugins, Themes, Konfigurationsänderungen, möglicherweise modifizierte Dateien im Core oder im vendor/-Verzeichnis selbst – composer install kennt diesen Kontext nicht. Es stellt den Zustand aus composer.lock wieder her, unabhängig davon, was zur Laufzeit tatsächlich vorhanden ist. Das Ergebnis kann funktionieren. Es kann aber auch zu stillen Inkonsistenzen führen, die sich erst später zeigen.
composer update ist nochmals eine andere Kategorie. Es berechnet die Abhängigkeitsmatrix neu und verlässt damit den getesteten Zustand des Projekts vollständig. LimeSurvey-Releases basieren auf konkret getesteten Dependency-Kombinationen – nicht nur formal durch Constraints definiert, sondern durch reale Tests abgesichert. Ein composer update erzeugt einen neuen Zustand, der formal zulässig ist, aber außerhalb dieses getesteten Spektrums liegt. Laufzeitfehler ohne offensichtliche Ursache, Inkompatibilitäten in indirekten Abhängigkeiten, schwer reproduzierbare Bugs – das sind die typischen Folgen.
Das richtige mentale Modell
Wer LimeSurvey mit den Erwartungen eines modernen Composer-Projekts betreibt, wird zwangsläufig in Widersprüche laufen. Composer verhält sich unerwartet, Deployments sind nicht deterministisch im gewohnten Sinn, der tatsächliche Zustand weicht vom erwarteten Modell ab. Das liegt nicht an Composer. Es liegt daran, dass das zugrunde liegende Modell ein anderes ist.
Das passende mentale Modell ist das einer ausgelieferten Anwendung: Der Core ist ein Artefakt, das als Ganzes übernommen wird. Erweiterungen – Plugins und Themes – liegen in der Verantwortung des Betreibers. Der Core-Zustand selbst ist kein Ausgangsmaterial, das neu zusammengesetzt werden soll. git clone oder Release-Download als Ausgangspunkt, keine Dependency-Eingriffe im Core, Anpassungen ausschließlich über die vorgesehenen Erweiterungspunkte. Wer darüber hinaus Reproduzierbarkeit und Kontrolle benötigt, braucht einen eigenen Build-Prozess – Composer im Build-Schritt, nicht im Deployment.
Fazit
LimeSurvey nutzt Composer – aber nicht im Sinne eines klassischen Composer-first-Projekts. Der vendor/-Ordner ist Teil des Repositorys, der Checkout ist direkt lauffähig, und Composer ist primär ein internes Werkzeug des Projekts. Das ist kein Fehler, sondern eine historisch gewachsene Architekturentscheidung.
Das Distributions-Modell hat seinen Preis: Kontrolle über Abhängigkeiten, Reproduzierbarkeit, saubere Artefaktgrenzen – das alles ist schwieriger als in einem modernen Composer-Projekt. Aber es ist das Modell, das LimeSurvey seit Jahren stabil hält. Wer es als solches akzeptiert, statt es zu bekämpfen, kommt deutlich weiter.