fix: probe container bridge network IP in healthcheck (#3151) (#3434)

Integrated into release/v3.8.17
This commit is contained in:
Benjamin
2026-06-08 23:43:50 +02:00
committed by GitHub
parent 2427df2f2c
commit 3c98e9f1ef

View File

@@ -11,13 +11,36 @@
* error, so the container was reported `unhealthy` with an empty, undiagnosable
* `State.Health[].Output`. We now try an ordered list of hosts and surface the
* last error on total failure.
*
* Bridge Network Fix: Also probes the container's internal bridge IP (e.g., 172.17.0.2)
* to handle Docker network setups that isolate loopback interfaces.
*/
import { pathToFileURL } from "node:url";
import { networkInterfaces } from "node:os";
const DEFAULT_HOSTS = ["127.0.0.1", "localhost", "::1"];
const DEFAULT_TIMEOUT_MS = 4000;
/**
* Get the primary non-loopback IPv4 address (container internal IP).
* Falls back to null if unable to determine.
*/
function getContainerInternalIP() {
try {
const interfaces = networkInterfaces();
for (const [name, addrs] of Object.entries(interfaces)) {
// Skip loopback and docker0, prioritize eth0/veth interfaces
if (name.startsWith("lo") || name === "docker0") continue;
const ipv4 = addrs?.find((a) => a.family === "IPv4" && !a.internal);
if (ipv4) return ipv4.address;
}
} catch {
// silently ignore if unable to read interfaces
}
return null;
}
/**
* Build the health URL for a host, bracketing IPv6 literals (e.g. `::1`).
* @param {string} host
@@ -64,8 +87,16 @@ export async function probeHealth({
async function main() {
const port = process.env.DASHBOARD_PORT || process.env.PORT || "20128";
// Build host list: defaults + detected container bridge IP
const hosts = [...DEFAULT_HOSTS];
const containerIP = getContainerInternalIP();
if (containerIP && !hosts.includes(containerIP)) {
hosts.push(containerIP);
}
try {
await probeHealth({ port });
await probeHealth({ port, hosts });
process.exit(0);
} catch (err) {
// Surface the failure so `docker inspect ... .State.Health[].Output` is