Serve the panel from a sub-path, and an Apache conf for /heos

The app assumed it lived at the server root: its links were /static/...
and its fetches /api/..., which behind a proxy at /heos resolve to the
wrong place, so the page would load and nothing on it would work.

It now takes the prefix from X-Forwarded-Prefix, and everything it
generates -- stylesheet, icons, the manifest's start_url, every fetch --
follows. Nothing changes when it is served from its own port.

deploy/heos.conf is the Apache side, restricted to the local network by
default, since this controls the speakers and the vhost it hangs off has
a public certificate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 21:57:16 +02:00
co-authored by Claude Opus 5
parent 6213bcf23f
commit 6d132f53ff
6 changed files with 79 additions and 7 deletions
+31
View File
@@ -0,0 +1,31 @@
# HEOS panel behind Apache, at /heos
#
# sudo a2enmod proxy proxy_http headers
# sudo cp /var/www/html/heos/deploy/heos.conf /etc/apache2/conf-available/heos.conf
# sudo a2enconf heos
# sudo apachectl configtest && sudo systemctl reload apache2
#
# Apache reaches the panel on port 5005 (WEB_PORT in config.py). If you
# want it reachable ONLY through Apache, start it with --host 127.0.0.1;
# by default it also answers directly on the LAN at <pi-ip>:5005.
# This block also takes /heos away from the filesystem, so the source in
# /var/www/html/heos stops being reachable as static files.
<Location /heos>
# The panel controls the speakers, and it hangs off a vhost with a
# public certificate. Keep it to the house unless you mean otherwise:
# delete this RequireAny block to let it answer from anywhere.
<RequireAny>
Require ip 192.168.0.0/24
Require ip 127.0.0.1
Require ip ::1
</RequireAny>
# Tells the app it is mounted on a sub-path, so every link, icon and
# fetch it generates is /heos/... rather than /... Without this the
# page loads and nothing on it works.
RequestHeader set X-Forwarded-Prefix /heos
ProxyPass http://127.0.0.1:5005
ProxyPassReverse http://127.0.0.1:5005
</Location>