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
pull/1571/head
RoyK 1 year ago
parent caa1b94fd6
commit f656c2b46d
No known key found for this signature in database
GPG Key ID: EC258EDBB0F06DAC

@ -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]));
}
});

Loading…
Cancel
Save