From f656c2b46d5940a0ccdadb7bff73f4ba29e7030b Mon Sep 17 00:00:00 2001 From: RoyK Date: Mon, 5 Jun 2023 16:06:14 +0200 Subject: [PATCH] fix(service-helper): service detection with Docker Swarm The current implementation of service detection focusses on containers. However when using Docker Swarm this limits automatic service detection to the containers running on the same node as homepage (or docker-proxy). Detecting other services in the docker swarm is with the current implementation not possible. This commit fixes this by getting the appropriate labels from services when Docker swarm is configured in the config file. This ensures that the appropriate labels are gathered from the service definition instead of the container definiation, thus allowing for automatic service detection for the entire Docker swarm. Please note that in order for this to function the homepage (or dockerproxy) should be running on a manager node. Only the manager node is able to gather all the relevant service labels. Fixes: #752, #970, #955, #1255, #1045, #1496 --- src/utils/config/service-helpers.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js index 7f9d45e40..00c236eb7 100644 --- a/src/utils/config/service-helpers.js +++ b/src/utils/config/service-helpers.js @@ -62,11 +62,14 @@ export async function servicesFromDocker() { const serviceServers = await Promise.all( Object.keys(servers).map(async (serverName) => { + const isSwarm = servers[serverName].swarm ?? false; + try { + const listProperties = { all: true }; + const labelProperty = (isSwarm) ? 'Spec.Labels' : 'Labels'; + const nameProperty = (isSwarm) ? 'Spec.Name' : 'Name[0]'; const docker = new Docker(getDockerArguments(serverName).conn); - const containers = await docker.listContainers({ - all: true, - }); + const containers = await ((isSwarm) ? docker.listServices(listProperties) : docker.listContainers(listProperties)); // bad docker connections can result in a object? // in any case, this ensures the result is the expected array @@ -76,17 +79,18 @@ export async function servicesFromDocker() { const discovered = containers.map((container) => { let constructedService = null; + const labels = shvl.get(container, labelProperty); - Object.keys(container.Labels).forEach((label) => { + Object.keys(labels).forEach((label) => { if (label.startsWith("homepage.")) { if (!constructedService) { constructedService = { - container: container.Names[0].replace(/^\//, ""), + container: shvl.get(container, nameProperty).replace(/^\//, ""), server: serverName, type: 'service' }; } - shvl.set(constructedService, label.replace("homepage.", ""), substituteEnvironmentVars(container.Labels[label])); + shvl.set(constructedService, label.replace("homepage.", ""), substituteEnvironmentVars(labels[label])); } });