Link port chips to the Docker host, not the proxy's domain (0.67.3)
Ports published on 0.0.0.0 were linked at window.location.hostname. Opened
through a reverse proxy such as Nginx Proxy Manager that is the proxy's
domain, and domain:8080 ended up at the proxy instead of the container.
The backend now reads the host's address from the host's routing table
(${HOST_PROC_PATH}/1/net/route + fib_trie, the /proc mount the compose file
already has): the IPv4 address on the interface with the best default
route. There is no fallback to /proc/net, which in a bridged container is
the container's own namespace with an unreachable 172.x address.
The links use, in order: the new "Host address for port links" setting
(Settings -> General), the page's hostname when it is an IP or localhost,
the detected address, and the page's hostname as a last resort. Ports
bound to one specific address still link there; IPv6 hosts are bracketed.
The setting is validated before anything is written, so a bad value no
longer leaves the interval half-saved in the same request.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
06234c1067
commit
ba788e8b03
13 files changed
+432
-22
No files matched your search
@@ -0,0 +1,32 @@
|
||||
const WILDCARD_IPS = new Set(["", "0.0.0.0", "::"]);
|
||||
|
||||
/** IPv6 literals need brackets in a URL; location.hostname already has them. */
|
||||
export function urlHost(host: string): string {
|
||||
return host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
||||
}
|
||||
|
||||
function isIpLiteral(host: string): boolean {
|
||||
return /^\d{1,3}(\.\d{1,3}){3}$/.test(host) || host.startsWith("[");
|
||||
}
|
||||
|
||||
/** Where a port bound to all interfaces is reached. The page's own hostname
|
||||
* only works when it *is* the Docker host — behind a reverse proxy it is the
|
||||
* proxy's domain, and domain:8080 lands on the proxy. So: the configured
|
||||
* host, else the page's hostname when that is an IP (or localhost), else the
|
||||
* host address the backend detected, else the page's hostname after all. */
|
||||
export function defaultLinkHost(
|
||||
page: string,
|
||||
settings?: { port_link_host: string; detected_host_ip: string | null }
|
||||
): string {
|
||||
if (settings?.port_link_host) return settings.port_link_host;
|
||||
if (isIpLiteral(page) || page === "localhost") return page;
|
||||
return settings?.detected_host_ip || page;
|
||||
}
|
||||
|
||||
/** Pick the host to link to: an explicit override, the bound
|
||||
* host IP if it's a concrete address, otherwise the default above. */
|
||||
export function linkHost(hostIp: string | undefined, fallback: string, override?: string): string {
|
||||
if (override) return override;
|
||||
if (hostIp && !WILDCARD_IPS.has(hostIp)) return hostIp;
|
||||
return fallback;
|
||||
}
|
||||
Reference in new issue
Block a user