ZoneMinder lässt sich problemlos hinter einem Reverse Proxy betreiben, hat aber eine Eigenheit, die viele Setups zunächst scheitern lässt: Die Anwendung generiert ihre eigenen Links serverseitig aus SCRIPT_NAME und geht dabei fest von ihrem lokalen /zm-Pfad aus. Ein naiver Reverse-Proxy-Handler mit festem Pfad-Präfix führt deshalb zu doppelten oder fehlenden Pfaden – die Login-Seite lädt, aber Monitor-Kacheln und Live-Streams bleiben leer. Aus diesem Grund müssen für den Betrieb von ZoneMinder über einen Reverse Proxy mit Caddy zwei separate Handler eingerichtet werden:
Zwei Handler auf derselben Subdomain (Dienste → Caddy → Reverse Proxy → Handlers):
Handler A – /zm* (eigentlicher Proxy):
|
1 2 3 4 5 6 |
Pfad: /zm* Direktive: reverse_proxy Upstream-Domain: <ip> Upstream-Port: 80 Upstream-Pfad: (leer) |
Handler B – / (Redirect):
|
1 2 3 4 5 6 |
Pfad: / Direktive: redir Protokoll: https:// Upstream-Domain: zm.<domain> Upstream-Pfad: /zm/ |
Ergebnis (cat /usr/local/etc/caddy/Caddyfile | grep -B5 -A15 “zm.<domain>”):
|
1 2 3 4 5 6 7 8 9 |
zm.<domain> { handle /zm* { reverse_proxy <ip>:80 } handle / { redir https://zm.<domain>/zm/ } } |
Keine manuellen header_up-Einträge nötig: Caddy setzt Host, X-Forwarded-For, X-Forwarded-Proto und X-Forwarded-Host bereits automatisch. Nur falls das Backend explizit X-Real-IP statt X-Forwarded-For auswertet, müsste der zusätzlich gesetzt werden.
Warum zwei Handler statt einem mit festem Präfix: Ein einzelner Handler mit ToPath: /zm hängt den Präfix vor jeden Request – auch vor die, die ZM selbst schon mit /zm/... generiert. Ergebnis: doppelter Präfix, 404 bei AJAX-Requests, Monitore bleiben leer, obwohl Login lädt. Die Trennung in “Root → Redirect auf /zm/” und “/zm* → unverändert durchreichen” vermeidet das.
Bekannte Einschränkung: Nach dem Redirect zeigt die Adressleiste dauerhaft zm.<domain>/zm/..., weil ZM seine Links aus SCRIPT_NAME baut. Vermeidbar nur durch Eingriff auf dem ZM-Host selbst (Apache-Alias entfernen, ZM direkt unter / ausliefern).
GUI-Stolperfalle: Bei redir ist Upstream-Domain ein Pflichtfeld. Für einen Redirect innerhalb derselben Domain dort die eigene Domain (zm.<domain>), nicht die Backend-IP eintragen – sonst wird die interne Adresse im Browser sichtbar.
by Speefak