fix: docker hosts and ports env variable wrongly used (#2050)

* fix: docker hosts and ports env variable wrongly used

* fix: ci issues
This commit is contained in:
Meier Lukas
2025-01-22 20:43:54 +01:00
committed by GitHub
parent 470d27e091
commit 73f7d885cd
16 changed files with 313 additions and 91 deletions

View File

@@ -0,0 +1,18 @@
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
import { shouldSkipEnvValidation } from "@homarr/common/env-validation";
export const env = createEnv({
server: {
// Comma separated list of docker hostnames that can be used to connect to query the docker endpoints (localhost:2375,host.docker.internal:2375, ...)
DOCKER_HOSTNAMES: z.string().optional(),
DOCKER_PORTS: z.string().optional(),
},
runtimeEnv: {
DOCKER_HOSTNAMES: process.env.DOCKER_HOSTNAMES,
DOCKER_PORTS: process.env.DOCKER_PORTS,
},
skipValidation: shouldSkipEnvValidation(),
emptyStringAsUndefined: true,
});

View File

@@ -0,0 +1,10 @@
import type Docker from "dockerode";
export type { DockerInstance } from "./singleton";
export { DockerSingleton } from "./singleton";
export type { ContainerInfo, Container, Port } from "dockerode";
export type { Docker };
export const containerStates = ["created", "running", "paused", "restarting", "exited", "removing", "dead"] as const;
export type ContainerState = (typeof containerStates)[number];

View File

@@ -0,0 +1,53 @@
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 hostVariable = env.DOCKER_HOSTNAMES;
const portVariable = env.DOCKER_PORTS;
if (hostVariable === undefined || portVariable === undefined) {
return [{ host: "socket", instance: new Docker() }];
}
const hostnames = hostVariable.split(",");
const ports = portVariable.split(",");
if (hostnames.length !== ports.length) {
throw new Error("The number of hosts and ports must match");
}
return hostnames.map((host, i) => {
// Check above ensures that ports[i] is not undefined
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const port = ports[i]!;
return {
host: `${host}:${port}`,
instance: new Docker({
host,
port: parseInt(port, 10),
}),
};
});
}
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;
}
}