Files
homarr/packages/docker/src/singleton.ts
T

66 lines
1.9 KiB
TypeScript

import Docker from "dockerode";
import { env } from "./env";
export interface DockerInstance {
host: string;
instance: Docker;
}
export class DockerSingleton {
private static instances: DockerInstance[] | null = null;
private createInstances() {
const socketPaths = env.DOCKER_SOCKET_PATHS;
const hostVariable = env.DOCKER_HOSTNAMES;
const portVariable = env.DOCKER_PORTS;
// Socket instances from DOCKER_SOCKET_PATHS
const socketInstances: DockerInstance[] = socketPaths
? socketPaths.split(",").map((socketPath) => ({
host: socketPath,
instance: new Docker({ socketPath }),
}))
: [];
// TCP instances from existing DOCKER_HOSTNAMES/DOCKER_PORTS
let tcpInstances: DockerInstance[] = [];
if (hostVariable !== undefined && portVariable !== undefined) {
const hostnames = hostVariable.split(",");
const ports = portVariable.split(",");
if (hostnames.length !== ports.length) {
throw new Error("The number of hosts and ports must match");
}
tcpInstances = hostnames.map((host, i) => ({
host: `${host}:${ports[i]}`,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
instance: new Docker({ host, port: parseInt(ports[i]!, 10) }),
}));
}
const instances = [...socketInstances, ...tcpInstances];
// Default: local socket if nothing else configured
if (instances.length === 0) {
return [{ host: "socket", instance: new Docker() }];
}
return instances;
}
public static findInstance(host: string): DockerInstance | undefined {
return this.instances?.find((instance) => instance.host === host);
}
public static getInstances(): DockerInstance[] {
if (this.instances) {
return this.instances;
}
this.instances = new DockerSingleton().createInstances();
return this.instances;
}
}