Files
2026-03-28 13:41:29 +01:00

116 lines
3.3 KiB
JavaScript

const Docker = require('dockerode');
const os = require('os');
const ip = require('ip');
const docker = new Docker({ socketPath: '/var/run/docker.sock' });
function getHostIpAddresses() {
const interfaces = os.networkInterfaces();
const ipAddresses = [];
for (const interfaceName in interfaces) {
for (const iface of interfaces[interfaceName]) {
// Only consider IPv4 and non-internal addresses
if (iface.family === 'IPv4' && !iface.internal) {
ipAddresses.push({
address: iface.address,
netmask: iface.netmask,
cidr: iface.cidr,
});
}
}
}
return ipAddresses;
}
function isIpInSubnet(checkIp, subnetCidr) {
try {
return ip.cidrSubnet(subnetCidr).contains(checkIp);
} catch (e) {
console.error(`Error checking IP in subnet: ${e.message}`);
return false;
}
}
function getTraefikUrl(container) {
const ruleLabel = Object.keys(container.Labels).find(label => label.endsWith('.rule'));
if (ruleLabel) {
const rule = container.Labels[ruleLabel];
const match = rule.match(/Host\(`(.*?)`\)/);
if (match) {
return `http://${match[1]}`;
}
}
return null;
}
async function listContainers() {
const containers = await docker.listContainers();
const hostIpAddresses = getHostIpAddresses();
return containers
.filter(container => container.Ports.length > 0)
.map(container => {
const traefikUrl = getTraefikUrl(container);
const containerName = container.Names[0].substring(1);
const accessibleUrls = [];
let preferredLocalUrl = null;
// Get all container IPs
const containerIps = [];
for (const networkName in container.NetworkSettings.Networks) {
const network = container.NetworkSettings.Networks[networkName];
if (network.IPAddress) {
containerIps.push(network.IPAddress);
}
}
// Determine accessible URLs and preferred local URL
container.Ports.forEach(port => {
const publicPort = port.PublicPort;
const privatePort = port.PrivatePort;
// Add accessible URLs based on container IPs
containerIps.forEach(containerIp => {
const url = `http://${containerIp}:${privatePort}`;
accessibleUrls.push({ type: 'container', url: url, description: `Container IP: ${containerIp}` });
// Check for preferred local URL
if (!preferredLocalUrl) {
for (const hostIp of hostIpAddresses) {
if (isIpInSubnet(containerIp, hostIp.cidr)) {
preferredLocalUrl = `http://${hostIp.address}:${publicPort || privatePort}`;
break;
}
}
}
});
// Add accessible URLs based on host exposed ports
if (publicPort) {
hostIpAddresses.forEach(hostIp => {
const url = `http://${hostIp.address}:${publicPort}`;
accessibleUrls.push({ type: 'host', url: url, description: `Host IP: ${hostIp.address}` });
});
}
});
return {
id: container.Id,
name: containerName,
ports: container.Ports,
traefikUrl: traefikUrl,
preferredLocalUrl: preferredLocalUrl,
accessibleUrls: accessibleUrls,
labels: container.Labels,
};
});
}
module.exports = {
docker,
listContainers,
getHostIpAddresses,
};