From f14f12c778a9f2f441a7e8ee24e8d4512094f57e Mon Sep 17 00:00:00 2001 From: Vyacheslav Scherbinin Date: Tue, 11 Aug 2026 11:02:49 +0700 Subject: [PATCH] fix(compose): clean up mapping domain labels --- .../compose/domain/enabled-filter.test.ts | 49 +++++++++++++++++++ packages/server/src/utils/docker/domain.ts | 17 +++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts b/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts index bdb5d3e9f..c581dcdc0 100644 --- a/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts +++ b/apps/dokploy/__test__/compose/domain/enabled-filter.test.ts @@ -139,6 +139,55 @@ 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(\`frigate.example.com\`) + traefik.http.services.test-app-1-web.loadbalancer.server.port: 8971 + traefik.http.middlewares.stripprefix-test-app-1.stripprefix.prefixes: /api + custom.label: preserved +`, + ], + [ + "stack", + `services: + frigate: + image: frigate + deploy: + labels: + traefik.enable: "true" + traefik.http.routers.test-app-1-web.rule: Host(\`frigate.example.com\`) + traefik.http.services.test-app-1-web.loadbalancer.server.port: 8971 + traefik.http.middlewares.stripprefix-test-app-1.stripprefix.prefixes: /api + custom.label: preserved +`, + ], + ] as const)( + "removes stale mapping labels for a disabled domain from %s rebuilds", + async (composeType, staleComposeYaml) => { + composeYaml = staleComposeYaml; + + const result = await addDomainToCompose({ ...baseCompose, composeType }, [ + { ...baseDomain, enabled: false }, + ]); + + const service = result?.services?.frigate; + const labels = + composeType === "docker-compose" + ? service?.labels + : service?.deploy?.labels; + expect(labels).toMatchObject({ "custom.label": "preserved" }); + expect( + Object.keys(labels ?? {}).some((label) => label.includes("test-app-1")), + ).toBe(false); + }, + ); + 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 7c9dfb3dd..6c8443987 100644 --- a/packages/server/src/utils/docker/domain.ts +++ b/packages/server/src/utils/docker/domain.ts @@ -171,18 +171,25 @@ const removeDomainLabels = ( appName: string, uniqueConfigKey: number, ) => { - if (!Array.isArray(labels)) return labels; - const prefixes = [ `traefik.http.routers.${appName}-${uniqueConfigKey}-`, `traefik.http.services.${appName}-${uniqueConfigKey}-`, `traefik.http.middlewares.stripprefix-${appName}-${uniqueConfigKey}.`, `traefik.http.middlewares.addprefix-${appName}-${uniqueConfigKey}.`, ]; + const belongsToDomain = (label: string) => + prefixes.some((prefix) => label.startsWith(prefix)); - return labels.filter( - (label) => !prefixes.some((prefix) => label.startsWith(prefix)), - ); + if (Array.isArray(labels)) { + return labels.filter((label) => !belongsToDomain(label)); + } + if (labels) { + return Object.fromEntries( + Object.entries(labels).filter(([label]) => !belongsToDomain(label)), + ); + } + + return labels; }; export const addDomainToCompose = async (