refactor(traefik): migrate from Docker Swarm service to standalone container

This commit is contained in:
Mauricio Siu 2025-02-25 22:51:02 -06:00
parent 0a6382a731
commit 203da1a8fe

View File

@ -1,6 +1,6 @@
import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs"; import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path"; import path from "node:path";
import type { ContainerTaskSpec, CreateServiceOptions } from "dockerode"; import type { ContainerCreateOptions } from "dockerode";
import { dump } from "js-yaml"; import { dump } from "js-yaml";
import { paths } from "../constants"; import { paths } from "../constants";
import { pullImage, pullRemoteImage } from "../utils/docker/utils"; import { pullImage, pullRemoteImage } from "../utils/docker/utils";
@ -34,68 +34,53 @@ export const initializeTraefik = async ({
const { MAIN_TRAEFIK_PATH, DYNAMIC_TRAEFIK_PATH } = paths(!!serverId); const { MAIN_TRAEFIK_PATH, DYNAMIC_TRAEFIK_PATH } = paths(!!serverId);
const imageName = `traefik:v${TRAEFIK_VERSION}`; const imageName = `traefik:v${TRAEFIK_VERSION}`;
const containerName = "dokploy-traefik"; const containerName = "dokploy-traefik";
const settings: CreateServiceOptions = { const settings: ContainerCreateOptions = {
Name: containerName, name: containerName,
TaskTemplate: { Image: imageName,
ContainerSpec: { NetworkingConfig: {
Image: imageName, EndpointsConfig: {
Env: env, "dokploy-network": {},
Mounts: [ },
},
HostConfig: {
RestartPolicy: {
Name: "always",
},
Binds: [
`${MAIN_TRAEFIK_PATH}/traefik.yml:/etc/traefik/traefik.yml`,
`${DYNAMIC_TRAEFIK_PATH}:/etc/dokploy/traefik/dynamic`,
"/var/run/docker.sock:/var/run/docker.sock",
],
PortBindings: {
[`${TRAEFIK_SSL_PORT}/tcp`]: [
{ {
Type: "bind", HostPort: TRAEFIK_SSL_PORT.toString(),
Source: `${MAIN_TRAEFIK_PATH}/traefik.yml`,
Target: "/etc/traefik/traefik.yml",
},
{
Type: "bind",
Source: DYNAMIC_TRAEFIK_PATH,
Target: "/etc/dokploy/traefik/dynamic",
},
{
Type: "bind",
Source: "/var/run/docker.sock",
Target: "/var/run/docker.sock",
}, },
], ],
}, [`${TRAEFIK_PORT}/tcp`]: [
Networks: [{ Target: "dokploy-network" }], {
Placement: { HostPort: TRAEFIK_PORT.toString(),
Constraints: ["node.role==manager"], },
}, ],
}, ...(enableDashboard && {
Mode: { [`${8080}/tcp`]: [
Replicated: { {
Replicas: 1, HostPort: "8080",
}, },
}, ],
EndpointSpec: { }),
Ports: [ ...additionalPorts.map((port) => {
{ return {
TargetPort: 443, [`${port.targetPort}/tcp`]: [
PublishedPort: TRAEFIK_SSL_PORT,
PublishMode: "host",
},
{
TargetPort: 80,
PublishedPort: TRAEFIK_PORT,
PublishMode: "host",
},
...(enableDashboard
? [
{ {
TargetPort: 8080, HostPort: port.publishedPort.toString(),
PublishedPort: 8080,
PublishMode: "host" as const,
}, },
] ],
: []), };
...additionalPorts.map((port) => ({ }),
TargetPort: port.targetPort, },
PublishedPort: port.publishedPort,
PublishMode: port.publishMode || ("host" as const),
})),
],
}, },
Env: env,
}; };
const docker = await getRemoteDocker(serverId); const docker = await getRemoteDocker(serverId);
try { try {
@ -105,38 +90,28 @@ export const initializeTraefik = async ({
await pullImage(imageName); await pullImage(imageName);
} }
const service = docker.getService(containerName); const container = docker.getContainer(containerName);
const inspect = await service.inspect(); try {
const inspect = await container.inspect();
if (inspect.State.Status === "running") {
console.log("Traefik already running");
return;
}
const existingEnv = inspect.Spec.TaskTemplate.ContainerSpec.Env || []; await container.remove({ force: true });
const updatedEnv = !env ? existingEnv : env; console.log("Removed existing container");
} catch (error) {
console.log("Traefik Not Found: Starting1 ✅");
console.log(error);
}
const updatedSettings = { await docker.createContainer(settings);
...settings, const newContainer = docker.getContainer(containerName);
TaskTemplate: { await newContainer.start();
...settings.TaskTemplate,
ContainerSpec: {
...(settings?.TaskTemplate as ContainerTaskSpec).ContainerSpec,
Env: updatedEnv,
},
},
};
await service.update({
version: Number.parseInt(inspect.Version.Index),
...updatedSettings,
});
console.log("Traefik Started ✅"); console.log("Traefik Started ✅");
} catch (error) { } catch (error) {
try { console.log("Traefik Not Found: Starting2 ✅", error);
await docker.createService(settings);
} catch (error: any) {
if (error?.statusCode !== 409) {
throw error;
}
console.log("Traefik service already exists, continuing...");
}
console.log("Traefik Not Found: Starting ✅");
} }
}; };