Add an nginx version of the /heos proxy
Same contract as the Apache one -- strip the prefix off the request, tell the app about it with X-Forwarded-Prefix, keep it to the local network -- with the two things nginx needs that Apache did not: a redirect for the bare /heos, which would otherwise miss the location and fall through to the filesystem, and the trailing slash on proxy_pass that does the stripping. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -104,9 +104,9 @@ WantedBy=multi-user.target
|
|||||||
sudo systemctl enable --now heos-panel
|
sudo systemctl enable --now heos-panel
|
||||||
```
|
```
|
||||||
|
|
||||||
## Behind Apache, at /heos
|
## Behind a reverse proxy, at /heos
|
||||||
|
|
||||||
`deploy/heos.conf` reverse-proxies `/heos` to the panel:
|
`deploy/heos.conf` reverse-proxies `/heos` to the panel with Apache:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo a2enmod proxy proxy_http headers
|
sudo a2enmod proxy proxy_http headers
|
||||||
@@ -115,11 +115,16 @@ sudo a2enconf heos
|
|||||||
sudo apachectl configtest && sudo systemctl reload apache2
|
sudo apachectl configtest && sudo systemctl reload apache2
|
||||||
```
|
```
|
||||||
|
|
||||||
It ships restricted to the local network — it controls the speakers, and
|
`deploy/heos.nginx.conf` is the same thing for nginx: copy it to
|
||||||
it usually hangs off a vhost with a public certificate. Delete the
|
`/etc/nginx/snippets/heos.conf`, `include snippets/heos.conf;` inside the
|
||||||
`RequireAny` block to open it up.
|
`server` block, then `sudo nginx -t && sudo systemctl reload nginx`.
|
||||||
|
|
||||||
The app works at either address without being told which. Apache sends
|
Both ship restricted to the local network — this controls the speakers, and
|
||||||
|
it usually hangs off a host with a public certificate. Delete the
|
||||||
|
`RequireAny` block (Apache) or the `allow`/`deny` lines (nginx) to open it
|
||||||
|
up.
|
||||||
|
|
||||||
|
The app works at either address without being told which. The proxy sends
|
||||||
`X-Forwarded-Prefix: /heos`, and every URL the app generates — stylesheet,
|
`X-Forwarded-Prefix: /heos`, and every URL the app generates — stylesheet,
|
||||||
icons, the manifest's `start_url`, every `fetch` — picks up that prefix.
|
icons, the manifest's `start_url`, every `fetch` — picks up that prefix.
|
||||||
Serve it straight from port 5005 and the same URLs come out as `/...`.
|
Serve it straight from port 5005 and the same URLs come out as `/...`.
|
||||||
@@ -128,8 +133,8 @@ and nothing on it works.
|
|||||||
|
|
||||||
Two things worth knowing:
|
Two things worth knowing:
|
||||||
|
|
||||||
- The `<Location>` block takes `/heos` away from the filesystem, so the
|
- The proxy block takes `/heos` away from the filesystem, so the source
|
||||||
source under `/var/www/html/heos` stops being served as static files.
|
under `/var/www/html/heos` stops being served as static files.
|
||||||
- The panel still answers directly on `<pi-ip>:5005`. Start it with
|
- The panel still answers directly on `<pi-ip>:5005`. Start it with
|
||||||
`--host 127.0.0.1` if you want Apache to be the only way in.
|
`--host 127.0.0.1` if you want Apache to be the only way in.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# HEOS panel behind nginx, at /heos
|
||||||
|
#
|
||||||
|
# sudo cp /var/www/html/heos/deploy/heos.nginx.conf /etc/nginx/snippets/heos.conf
|
||||||
|
# then inside the server { } block that serves the site:
|
||||||
|
# include snippets/heos.conf;
|
||||||
|
# sudo nginx -t && sudo systemctl reload nginx
|
||||||
|
#
|
||||||
|
# nginx reaches the panel on port 5005 (WEB_PORT in config.py). If you want
|
||||||
|
# it reachable ONLY through nginx, start it with --host 127.0.0.1; by
|
||||||
|
# default it also answers directly on the LAN at <pi-ip>:5005.
|
||||||
|
|
||||||
|
# A bare /heos would miss the location below and fall through to the
|
||||||
|
# filesystem, so send it to the slashed form first.
|
||||||
|
location = /heos {
|
||||||
|
return 301 /heos/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /heos/ {
|
||||||
|
# The panel controls the speakers, and it usually hangs off a host
|
||||||
|
# with a public certificate. Keep it to the house unless you mean
|
||||||
|
# otherwise: drop these four lines to let it answer from anywhere.
|
||||||
|
allow 192.168.0.0/24;
|
||||||
|
allow 127.0.0.1;
|
||||||
|
allow ::1;
|
||||||
|
deny all;
|
||||||
|
|
||||||
|
# The trailing slash on proxy_pass is what strips /heos/ back off
|
||||||
|
# before the request reaches the app.
|
||||||
|
proxy_pass http://127.0.0.1:5005/;
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
proxy_set_header X-Forwarded-Prefix /heos;
|
||||||
|
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Giving it a host of its own instead? Then it is not on a sub-path, and
|
||||||
|
# the X-Forwarded-Prefix line above is the one thing to leave out:
|
||||||
|
#
|
||||||
|
# server {
|
||||||
|
# server_name heos.example.com;
|
||||||
|
# location / {
|
||||||
|
# proxy_pass http://127.0.0.1:5005;
|
||||||
|
# proxy_set_header Host $host;
|
||||||
|
# proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
Reference in New Issue
Block a user