feat: init
This commit is contained in:
114
backend/docker.js
Normal file
114
backend/docker.js
Normal file
@@ -0,0 +1,114 @@
|
||||
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,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
docker,
|
||||
listContainers,
|
||||
getHostIpAddresses,
|
||||
};
|
||||
Reference in New Issue
Block a user