Admin Intelligence
Ihre Linux Server
Administratoren

Persönlich – kompetent – schnell

Linux Server Administration Cloud & Virtualisierung Monitoring & Backup Kosteneffizienz & Transparenz Open Source Lösungen IT-Security
DACH-Region Hosting in Deutschland

Moodle Router einrichten: Apache und Nginx für Moodle 5.x

Das Upgrade auf Moodle 5.x ist durchgelaufen, der Login funktioniert, die Startseite lädt. Dann klickt die erste Trainerin auf „Meine Kurse“ und bekommt einen 404-Fehler. Oder Moodle meldet nach dem Update, dass Composer-Abhängigkeiten fehlen.

Beides hat dieselbe Ursache: Seit Moodle 5.x hängt deutlich mehr an der Webserver-Konfiguration als früher. Der Moodle Router (r.php) übernimmt nach und nach das Ausliefern von Seiten, der DocumentRoot zieht nach /public um, und externe Bibliotheken kommen per Composer. In diesem Beitrag zeigen wir, wie Sie den Moodle Router unter Apache und Nginx sauber einrichten, welche drei Zeilen in der Praxis über „läuft“ oder „404“ entscheiden und wie Sie das Ergebnis zuverlässig testen.

Was der Moodle Router ist und warum Moodle 5.x ihn braucht

Klassisch ist Moodle eine Sammlung einzelner PHP-Dateien: /course/view.php, /my/index.php und so weiter. Der Webserver sucht die Datei und übergibt sie an PHP.

Der Router ändert dieses Prinzip. Moodle nutzt ihn als sogenannten Front Controller: Anfragen, zu denen keine echte Datei existiert, landen bei r.php, und Moodle entscheidet selbst, welcher Code die Antwort liefert. Das ermöglicht saubere URLs und ist die Grundlage für die neue REST-API unter /api/rest/v2/.

Der Router ist seit Moodle 4.5 an Bord und wird mit jeder Version wichtiger:

  • Moodle 4.5: erste Implementierung des Routing-Systems
  • Moodle 5.0: auch normale Seiten können über den Router ausgeliefert werden
  • Moodle 5.1: neue Verzeichnisstruktur mit /public als DocumentRoot
  • Moodle 5.2: eigener Router-Test im Bericht „Systemstatus“

Ob die Router-Konfiguration in 5.1 schon Pflicht ist, beantwortet die offizielle Dokumentation übrigens widersprüchlich. Die Router-Seite nennt sie „compulsory“, die Release Notes zu 5.1 sprechen von „strongly recommended“ mit Kompatibilitätsschicht. Ein Blick in die config-dist.php schafft Klarheit: $CFG->routerconfigured steht dort noch auf false, mit dem Hinweis, dass sich der Standard in einer künftigen Version ändert. Unsere Empfehlung ist deshalb eindeutig: Richten Sie den Router jetzt ein, solange Sie es geplant tun können, und nicht erst, wenn ein Update es erzwingt.

Voraussetzung: DocumentRoot auf /public umstellen

Seit Moodle 5.1 liegen alle öffentlich erreichbaren Dateien im Unterordner public. Die config.php bleibt dagegen im Moodle-Hauptverzeichnis und ist damit nicht mehr direkt aus dem Web erreichbar. Für den Webserver heißt das:

  • Der DocumentRoot zeigt auf /var/www/moodle/public, nicht mehr auf /var/www/moodle.
  • $CFG->wwwroot in der config.php bleibt unverändert, also ohne /public am Ende. Moodle bricht sonst bewusst mit einem Fehler ab.
  • Zusatz-Plugins müssen nach dem Upgrade unter Umständen manuell in die passende Struktur unterhalb von public verschoben werden.

Die organisatorische Seite dieser Umstellung, vom Testsystem bis zum Rollback-Plan, beschreiben wir ausführlich in unserem Beitrag zur Moodle Migration von 4.5 auf 5.1. Hier geht es um den technischen Teil danach.

Moodle 5 Apache Konfiguration mit php-fpm

Die meisten Moodle-Installationen, die wir betreuen, laufen auf Apache mit mpm_event und php-fpm. Für diese Kombination braucht der Router drei Bausteine. Fehlt einer davon, läuft Moodle scheinbar normal, aber einzelne Bereiche liefern 404-Fehler.

So sieht der relevante Teil eines funktionierenden vHosts aus:

<VirtualHost *:443>
    ServerName moodle.example.de
    DocumentRoot /var/www/moodle/public

    <Directory /var/www/moodle/public>
        AllowOverride None
        Require all granted

        # 1. Nur index.php als Verzeichnis-Index
        DirectoryIndex index.php

        # 2. Alles, was keine echte Datei ist, an den Router
        FallbackResource /r.php

        # 3. Nicht existierende *.php-Pfade ebenfalls an den Router
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule \.php$ /r.php [L]
    </Directory>

    # SSL-Konfiguration, Logs usw. wie gehabt
</VirtualHost>

FallbackResource /r.php

FallbackResource ist der Kern. Apache liefert weiterhin jede existierende Datei direkt aus.

Nur wenn keine passende Datei existiert, übergibt Apache die Anfrage an /r.php. Der Pfad ist relativ zum DocumentRoot. Liegt Moodle in einem Unterverzeichnis, passen Sie ihn entsprechend an, etwa /moodle/r.php.

DirectoryIndex index.php: die unscheinbare Stolperfalle

Diese Zeile wirkt überflüssig, ist es aber nicht. Debian und Ubuntu setzen standardmäßig DirectoryIndex index.html index.cgi index.pl index.php ….

Ruft jemand /course/ auf, prüft Apache per internem Subrequest zuerst, ob /course/index.html existiert. Die Datei gibt es nicht, also greift FallbackResource, und der Router beantwortet den Subrequest mit 404. Apache kommt gar nicht mehr bis zur index.php.

Das Ergebnis: Einzelne Seiten wie /course/view.php?id=5 funktionieren, aber alle Verzeichnis-URLs wie /, /course/ oder /my/ liefern 404. Genau dieses Muster haben wir bei einer Umstellung selbst erlebt, und es ist tückisch, weil ein schneller Test auf eine Kursseite grünes Licht gibt. Mit DirectoryIndex index.php direkt vor dem FallbackResource ist das Problem erledigt.

RewriteRule für nicht existierende .php-Pfade

Der dritte Baustein betrifft nur Setups mit php-fpm. Dort ist PHP meist per SetHandler für alle Pfade auf .php eingebunden.

Der Router kennt aber auch Routen, die auf .php enden, ohne dass eine echte Datei dahinter liegt. Apache reicht solche Anfragen direkt an php-fpm weiter, php-fpm findet keine Datei und antwortet mit „File not found“. FallbackResource kommt nie zum Zug. Im Apache-Error-Log steht dazu die Meldung AH01071: Got error 'Primary script unknown'.

php-fpm antwortet auf einen nicht existierenden PHP-Pfad mit File not found

Die RewriteRule fängt das ab: Existiert die angefragte .php-Datei nicht, geht die Anfrage an /r.php. Moodle prüft genau diesen Fall im Systemstatus als eigenen Test („routed page with path ending in .php“).

Hinweis: Die Rewrite-Regeln setzen mod_rewrite voraus. Aktivieren Sie es bei Bedarf mit a2enmod rewrite und laden Sie Apache danach neu.

Nginx: das Gegenstück zum FallbackResource

Nginx kennt keine Konfiguration pro Verzeichnis, alles steht zentral im server-Block. Die Moodle-Dokumentation empfiehlt:

server {
    server_name moodle.example.de;
    root /var/www/moodle/public;
    index index.php;

    location / {
        try_files $uri $uri/ /r.php$is_args$args;
    }

    # Bestehender PHP-Block (fastcgi_pass an php-fpm) bleibt erhalten
}

try_files übernimmt hier die Rolle von FallbackResource: erst die echte Datei, dann das Verzeichnis, sonst der Router. Durch index index.php tritt das DirectoryIndex-Problem von Apache unter Nginx nicht auf. Prüfen Sie aber auch hier, wie Ihr PHP-Location-Block mit .php-Pfaden umgeht, für die keine Datei existiert. Der Systemstatus-Test zeigt Ihnen zuverlässig, ob dieser Fall funktioniert.

Moodle mitteilen, dass der Router konfiguriert ist

Ist der Webserver eingerichtet, fehlt eine Zeile in der config.php im Moodle-Hauptverzeichnis (nicht in public):

$CFG->routerconfigured = true;

Ohne diese Einstellung erzeugt Moodle Router-URLs weiterhin mit r.php im Pfad, also etwa /r.php/api/rest/v2/.... Mit der Einstellung entfällt r.php, und die URLs werden sauber. Setzen Sie den Wert erst, wenn der Webserver wirklich fertig konfiguriert ist. Sonst erzeugt Moodle Links, die ins Leere laufen.

Composer und vendor/: „Composer-Abhängigkeiten wurden nicht gefunden“

Ein zweiter Stolperstein bei Moodle 5.x hat mit dem Router nur indirekt zu tun, tritt aber oft im selben Wartungsfenster auf. Ab Moodle 5.1 bezieht Moodle externe PHP-Bibliotheken über Composer. Das Verzeichnis vendor/ steht in der .gitignore. Wer Moodle per Git installiert oder aktualisiert, hat es also schlicht nicht. Moodle meldet dann in der Umgebungsprüfung:

Composer-Abhängigkeiten wurden nicht gefunden. Stellen Sie bitte sicher, dass der Befehl „composer install –no-dev –classmap-authoritative“ im Moodle-Verzeichnis ausgeführt wurde.

Die Lösung ist genau dieser Befehl, ausgeführt im Moodle-Hauptverzeichnis als Webserver-Benutzer:

apt install composer
cd /var/www/moodle
sudo -u www-data composer install --no-dev --classmap-authoritative

Die Parameter haben einen Zweck: --no-dev lässt Entwickler-Pakete weg, die auf einem Produktivsystem nichts verloren haben. --classmap-authoritative optimiert den Autoloader. Moodle prüft beides in der Umgebungsprüfung und warnt, wenn Entwickler-Abhängigkeiten installiert sind oder der Autoloader nicht optimiert ist.

Wichtig: Diese Composer-Prüfungen sind in Moodle 5.1 bis 5.3 nur als „optional“ eingestuft. Ein fehlendes vendor/ blockiert das Upgrade also nicht. Das Upgrade läuft durch, und der Hinweis taucht nur unter „Weitere Prüfungen“ in der Umgebungsprüfung auf, wo ihn im Alltag kaum jemand bemerkt. Nehmen Sie composer install deshalb fest in Ihren Update-Ablauf auf, direkt nach dem Aktualisieren des Codes und vor admin/cli/upgrade.php.

Moodle Serverumgebung meldet fehlende Composer-Abhängigkeiten

Den Moodle Router testen

Ein Blick auf die Startseite reicht als Test nicht. Gehen Sie nach jeder Änderung an der Webserver-Konfiguration diese Punkte durch.

Systemstatus in Moodle prüfen

Ab Moodle 5.2 finden Sie unter Website-Administration › Berichte › Systemstatus den Eintrag „Router-Konfiguration“. Moodle schickt dabei echte HTTP-Anfragen an sich selbst und prüft fünf Fälle:

TestErwartet
Standard-Seite über den Router200
REST-API (/api/rest/v2/openapi.json)200
Nicht existierende Seite404
Weitergeleitete Seite mit echter Datei302
Router-Pfad, der auf .php endet302

Ist etwas falsch, zeigt der Bericht „Fehler“ mit dem Hinweis „Der Router ist nicht richtig konfiguriert.“ Steht $CFG->routerconfigured nicht auf true, führt Moodle die fünf Tests gar nicht erst aus. Zusätzlich erscheint ab Moodle 5.2 in der Umgebungsprüfung unter Website-Administration › Server › Serverumgebung der Hinweis „Der Router ist nicht konfiguriert.“

Moodle Systemstatus meldet einen Fehler bei der Router-Konfiguration

Verzeichnis-URLs per curl testen

Den DirectoryIndex-Fehler deckt der Systemstatus nicht ab. Testen Sie Verzeichnis-URLs deshalb zusätzlich von der Shell:

for p in / /course/ /my/ /login/; do
  printf '%-10s %s\n' "$p" "$(curl -s -o /dev/null -w '%{http_code}' https://moodle.example.de$p)"
done

Erwartet werden 200 oder eine Weiterleitung (303) zur Anmeldung, aber niemals 404. Steht eine Firewall oder ein Proxy vor dem Server, testen Sie direkt auf dem Server mit curl --resolve moodle.example.de:443:127.0.0.1.

Den APCu-Cache von php-fpm nicht vergessen

Ein letzter Praxistipp: Nutzt Ihre Installation APCu als Anwendungscache, haben CLI und php-fpm getrennte Caches. admin/cli/purge_caches.php und admin/cli/maintenance.php --disable erreichen den Cache von php-fpm nicht. Im schlimmsten Fall liefert Moodle nach dem Upgrade weiterhin die Wartungsseite aus, obwohl der Wartungsmodus längst beendet ist. Laden Sie php-fpm nach Upgrade und Cache-Leerung deshalb neu:

systemctl reload php8.4-fpm

Fazit: drei Zeilen mit großer Wirkung

Der Moodle Router ist kein exotisches Zusatzfeature, sondern die Richtung, in die sich Moodle entwickelt. Wer ihn jetzt sauber einrichtet, spart sich beim nächsten Major-Update eine böse Überraschung. Die wichtigsten Punkte im Überblick:

  • DocumentRoot auf /public, wwwroot ohne /public
  • Apache: DirectoryIndex index.php, FallbackResource /r.php und bei php-fpm die RewriteRule für .php-Pfade
  • Nginx: try_files $uri $uri/ /r.php$is_args$args
  • $CFG->routerconfigured = true erst nach erfolgreicher Webserver-Konfiguration
  • composer install --no-dev --classmap-authoritative fest in den Update-Ablauf aufnehmen
  • Nach Änderungen: Systemstatus prüfen, Verzeichnis-URLs per curl testen, php-fpm neu laden

Weitere Tipps zur Absicherung Ihrer Lernplattform finden Sie in unserem Beitrag Moodle Sicherheit Best Practise.

Sie möchten Ihre Lernplattform lieber in erfahrene Hände geben? Wir übernehmen Moodle Betrieb und Wartung inklusive Upgrades auf Moodle 5.x.

Und wenn Sie nicht sicher sind, ob Ihre Installation schon richtig konfiguriert ist, hilft ein Moodle Check-up. Falls Sie bei der Umstellung auf den Router hängen bleiben, melden Sie sich gerne bei uns. Unser Team hilft Ihnen bei der Konfiguration.