From 5ceb88bebe38e0e528cceee4c1f507a21fea7fbe Mon Sep 17 00:00:00 2001 From: Vyacheslav Scherbinin Date: Tue, 11 Aug 2026 12:29:49 +0700 Subject: [PATCH] fix(compose): regenerate mapping domain labels --- .../compose/domain/enabled-filter.test.ts | 53 +++++++++++++++++++ packages/server/src/utils/docker/domain.ts | 42 +++++++-------- 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts b/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts index 47de73f31..1cb696e07 100644 --- a/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts +++ b/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts @@ -237,6 +237,59 @@ describe("addDomainToCompose enabled filtering", () => { }, ); + it.each([ + [ + "docker-compose", + `services: + frigate: + image: frigate + labels: + traefik.enable: "true" + traefik.http.routers.test-app-1-web.rule: Host(\`old.example.com\`) + traefik.http.services.test-app-1-web.loadbalancer.server.port: 8971 + custom.label: preserved +`, + "traefik.docker.network", + ], + [ + "stack", + `services: + frigate: + image: frigate + deploy: + labels: + traefik.enable: "true" + traefik.http.routers.test-app-1-web.rule: Host(\`old.example.com\`) + traefik.http.services.test-app-1-web.loadbalancer.server.port: 8971 + custom.label: preserved +`, + "traefik.swarm.network", + ], + ] as const)( + "regenerates routing in mapping labels for an enabled domain in %s", + async (composeType, mappingComposeYaml, networkLabel) => { + composeYaml = mappingComposeYaml; + + const result = await addDomainToCompose({ ...baseCompose, composeType }, [ + { ...baseDomain, enabled: true }, + ]); + + const service = result?.services?.frigate; + const labels = + composeType === "docker-compose" + ? service?.labels + : service?.deploy?.labels; + expect(labels).toMatchObject({ + "custom.label": "preserved", + "traefik.enable": "true", + [networkLabel]: "dokploy-network", + "traefik.http.routers.test-app-1-web.rule": + "Host(`frigate.example.com`)", + "traefik.http.services.test-app-1-web.loadbalancer.server.port": "8971", + }); + }, + ); + it("emits labels only for the enabled domain when both are present", async () => { const result = await addDomainToCompose(baseCompose, [ { ...baseDomain, host: "enabled.example.com", enabled: true }, diff --git a/packages/server/src/utils/docker/domain.ts b/packages/server/src/utils/docker/domain.ts index d7b891475..a7256cfa2 100644 --- a/packages/server/src/utils/docker/domain.ts +++ b/packages/server/src/utils/docker/domain.ts @@ -282,33 +282,31 @@ export const addDomainToCompose = async ( labels = result.services[serviceName].deploy.labels; } + const networkLabel = + compose.composeType === "docker-compose" + ? "traefik.docker.network" + : "traefik.swarm.network"; + const networkName = compose.isolatedDeployment + ? compose.suffix || compose.appName + : "dokploy-network"; + if (Array.isArray(labels)) { if (!labels.includes("traefik.enable=true")) { labels.unshift("traefik.enable=true"); } labels.unshift(...httpLabels); - if (!compose.isolatedDeployment) { - if (compose.composeType === "docker-compose") { - if (!labels.includes("traefik.docker.network=dokploy-network")) { - labels.unshift("traefik.docker.network=dokploy-network"); - } - } else { - // Stack Case - if (!labels.includes("traefik.swarm.network=dokploy-network")) { - labels.unshift("traefik.swarm.network=dokploy-network"); - } - } - } else { - const isolatedNetwork = compose.suffix || compose.appName; - if (compose.composeType === "docker-compose") { - if (!labels.includes(`traefik.docker.network=${isolatedNetwork}`)) { - labels.unshift(`traefik.docker.network=${isolatedNetwork}`); - } - } else { - if (!labels.includes(`traefik.swarm.network=${isolatedNetwork}`)) { - labels.unshift(`traefik.swarm.network=${isolatedNetwork}`); - } - } + const networkLabelEntry = `${networkLabel}=${networkName}`; + if (!labels.includes(networkLabelEntry)) { + labels.unshift(networkLabelEntry); + } + } else if (labels) { + labels["traefik.enable"] = "true"; + labels[networkLabel] = networkName; + for (const label of httpLabels) { + const separatorIndex = label.indexOf("="); + labels[label.slice(0, separatorIndex)] = label.slice( + separatorIndex + 1, + ); } }