mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 11:58:14 +00:00
fix: don't show a bogus container IP for the network address under Docker
/api/network reported the container's bridge IP (172.x) when running in Docker, which surfaced as a broken/"Error" value in Settings → About & updates. Skip container-internal interfaces (detected via /.dockerenv) so the endpoint returns no address inside a container, and guard the panel against an unexpected response shape — both paths fall back to the helpful "open via the server's IP" hint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
// GET /api/network — best-effort discovery of LAN addresses other departments
|
||||
// can use to reach temetro, for the Settings "Network access" panel.
|
||||
//
|
||||
// Caveat: inside Docker's default bridge network this sees the container's IPs,
|
||||
// not the host's LAN IP, so the frontend prefers the address the browser is
|
||||
// actually using (window.location) and treats this as a fallback/hint.
|
||||
// Caveat: inside Docker's network this sees the container's bridge IP (e.g.
|
||||
// 172.x), not the host's LAN IP. Surfacing that bogus address looked like an
|
||||
// error in Settings, so when we detect we're in a container we return NO
|
||||
// addresses — the frontend then prefers the address the browser is actually
|
||||
// using (window.location) and otherwise shows a helpful "open via the server's
|
||||
// IP" hint instead of an unreachable container IP.
|
||||
import { existsSync } from "node:fs";
|
||||
import { networkInterfaces } from "node:os";
|
||||
|
||||
import { Router } from "express";
|
||||
@@ -19,16 +23,24 @@ function frontendPort(): number {
|
||||
}
|
||||
}
|
||||
|
||||
// True when running inside a container: the interface IPs are the container's
|
||||
// bridge network, not the host's reachable LAN address.
|
||||
function inContainer(): boolean {
|
||||
return existsSync("/.dockerenv") || process.env.RUNNING_IN_DOCKER === "true";
|
||||
}
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", (_req, res) => {
|
||||
const port = frontendPort();
|
||||
const addresses: string[] = [];
|
||||
for (const iface of Object.values(networkInterfaces())) {
|
||||
for (const net of iface ?? []) {
|
||||
// Node <18 reports family as "IPv4"; >=18 may report the number 4.
|
||||
const isV4 = net.family === "IPv4" || (net.family as unknown) === 4;
|
||||
if (isV4 && !net.internal) addresses.push(net.address);
|
||||
if (!inContainer()) {
|
||||
for (const iface of Object.values(networkInterfaces())) {
|
||||
for (const net of iface ?? []) {
|
||||
// Node <18 reports family as "IPv4"; >=18 may report the number 4.
|
||||
const isV4 = net.family === "IPv4" || (net.family as unknown) === 4;
|
||||
if (isV4 && !net.internal) addresses.push(net.address);
|
||||
}
|
||||
}
|
||||
}
|
||||
res.json({
|
||||
|
||||
Reference in New Issue
Block a user