Files
homelable/docker/nginx.standalone.subpath.conf.template
T
Pouzor 4e8d841807 feat(deploy): serve Homelable under a configurable base path
Homelable could only own the root of an origin. Behind an existing proxy
at `https://home.example/homelab/` the built `index.html` still asked for
`/assets/*`, which fell through to whatever owned the root — and when
that answered `text/html` for a `<script>` under `nosniff`, the browser
failed the load on an HTTP 200. The only workaround was patching the
checkout and rebuilding on every upgrade.

One build-time knob, `VITE_BASE_PATH`, becomes Vite's `base`. Vite
rewrites the asset URLs it emits; everything the app builds by hand goes
through the new `utils/basePath.ts` — the axios instances, the WebSocket
URL, the live-view route, the local brand icons, and the OIDC login href.
`resolveServerPath` covers what the *backend* hands back, which is always
root-absolute because it cannot know where the SPA is mounted: uploaded
floor-plan URLs already stored in a canvas are resolved at render time,
so plans predating the move keep loading. The OIDC callback used to
redirect to `/`, dropping subpath users at the origin root after login;
it now reads the prefix back out of `OIDC_REDIRECT_URI`.

The default is `/`, and stays a no-op there by construction: every helper
returns the string it returned before, the root build output is unchanged
and both nginx sites are byte-identical to what shipped — the Docker
image copies `docker/nginx.conf` verbatim and the installer keeps its
original heredoc. Only a non-default prefix takes the generated config.

Those generated configs use `root`, never `alias`, since `alias` plus
`try_files` mis-resolves `$uri` — the Docker build lands the bundle in
the matching subdirectory, and the installer symlinks it under
`/var/www/homelable`. Both accept either reverse-proxy style, prefix
forwarded intact or already stripped, with no redirect loop between them,
and `absolute_redirect off` stops the no-slash 301 from eating the port.

Closes #334.

ha-relevant: maybe
2026-09-04 11:23:16 +02:00

27 lines
797 B
Plaintext

# Standalone (no backend) Homelable served under a subpath (__BASE__).
# Generated at image build time — see docker/nginx.subpath.conf.template.
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Relative Location headers — the port and scheme belong to whatever proxy is
# in front, not to this server block.
absolute_redirect off;
location = __BASE_NO_SLASH__ {
return 301 __BASE__;
}
# SPA fallback under the prefix — no backend proxy
location __BASE__ {
try_files $uri $uri/ __BASE__index.html;
}
# Same, for a front proxy that strips the prefix before forwarding
location / {
root /usr/share/nginx/html__BASE_NO_SLASH__;
try_files $uri $uri/ /index.html;
}
}