瀏覽代碼

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
RoyK 2 年之前
父節點
當前提交
f656c2b46d
共有 1 個文件被更改,包括 10 次插入6 次删除
  1. 10 6
      src/utils/config/service-helpers.js

+ 10 - 6
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 <Buffer ...> 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]));
             }
           });