From 3a17c9b9e826702a9178a0acee134626cd03ff16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Gonz=C3=A1lez?= Date: Sun, 16 Nov 2025 15:57:34 +0100 Subject: [PATCH 1/3] fix: ensure Compose Traefik domain labels are written to local daemons --- packages/server/src/utils/builders/compose.ts | 4 ++-- packages/server/src/utils/docker/domain.ts | 15 ++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/server/src/utils/builders/compose.ts b/packages/server/src/utils/builders/compose.ts index 7792ed11c..6ac5bf130 100644 --- a/packages/server/src/utils/builders/compose.ts +++ b/packages/server/src/utils/builders/compose.ts @@ -2,7 +2,7 @@ import { dirname, join } from "node:path"; import { paths } from "@dokploy/server/constants"; import type { InferResultType } from "@dokploy/server/types/with"; import boxen from "boxen"; -import { writeDomainsToComposeRemote } from "../docker/domain"; +import { writeDomainsToCompose } from "../docker/domain"; import { encodeBase64, getEnviromentVariablesObject, @@ -22,7 +22,7 @@ export const getBuildComposeCommand = async (compose: ComposeNested) => { const projectPath = join(COMPOSE_PATH, compose.appName, "code"); const exportEnvCommand = getExportEnvCommand(compose); - const newCompose = await writeDomainsToComposeRemote(compose, domains); + const newCompose = await writeDomainsToCompose(compose, domains); const logContent = ` App Name: ${appName} Build Compose 🐳 diff --git a/packages/server/src/utils/docker/domain.ts b/packages/server/src/utils/docker/domain.ts index a176a4560..2272f364e 100644 --- a/packages/server/src/utils/docker/domain.ts +++ b/packages/server/src/utils/docker/domain.ts @@ -102,7 +102,7 @@ export const readComposeFile = async (compose: Compose) => { return null; }; -export const writeDomainsToComposeRemote = async ( +export const writeDomainsToCompose = async ( compose: Compose, domains: Domain[], ) => { @@ -120,19 +120,16 @@ echo "❌ Error: Compose file not found"; exit 1; `; } - if (compose.serverId) { - const composeString = stringify(composeConverted, { lineWidth: 1000 }); - const encodedContent = encodeBase64(composeString); - return `echo "${encodedContent}" | base64 -d > "${path}";`; - } + + const composeString = stringify(composeConverted, { lineWidth: 1000 }); + const encodedContent = encodeBase64(composeString); + return `echo "${encodedContent}" | base64 -d > "${path}";`; } catch (error) { // @ts-ignore - return `echo "❌ Has occured an error: ${error?.message || error}"; + return `echo "❌ Has occurred an error: ${error?.message || error}"; exit 1; `; } - - return ""; }; export const addDomainToCompose = async ( compose: Compose, From 4884ee33522f7062dd256a54cb094a6742c9e848 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Wed, 19 Nov 2025 00:22:29 -0600 Subject: [PATCH 2/3] feat: add KillBuild component and API mutation for terminating Docker builds - Introduced a new KillBuild component that allows users to terminate ongoing Docker builds for both applications and compose setups. - Implemented corresponding API mutations in the application and compose routers to handle build termination requests. - Enhanced queue setup with a killDockerBuild function to execute the termination commands on the server. --- .../application/deployments/kill-build.tsx | 65 +++++++++++++++++++ .../deployments/show-deployments.tsx | 4 ++ .../dokploy/server/api/routers/application.ts | 22 ++++++- apps/dokploy/server/api/routers/compose.ts | 21 +++++- apps/dokploy/server/queues/queueSetup.ts | 31 +++++++++ 5 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 apps/dokploy/components/dashboard/application/deployments/kill-build.tsx diff --git a/apps/dokploy/components/dashboard/application/deployments/kill-build.tsx b/apps/dokploy/components/dashboard/application/deployments/kill-build.tsx new file mode 100644 index 000000000..784534dd6 --- /dev/null +++ b/apps/dokploy/components/dashboard/application/deployments/kill-build.tsx @@ -0,0 +1,65 @@ +import { Scissors } from "lucide-react"; +import { toast } from "sonner"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; +import { api } from "@/utils/api"; + +interface Props { + id: string; + type: "application" | "compose"; +} + +export const KillBuild = ({ id, type }: Props) => { + const { mutateAsync, isLoading } = + type === "application" + ? api.application.killBuild.useMutation() + : api.compose.killBuild.useMutation(); + + return ( + + + + + + + Are you sure to kill the build? + + This will kill the build process + + + + Cancel + { + await mutateAsync({ + applicationId: id || "", + composeId: id || "", + }) + .then(() => { + toast.success("Build killed successfully"); + }) + .catch((err) => { + toast.error(err.message); + }); + }} + > + Confirm + + + + + ); +}; diff --git a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx index 1885ffc3a..7f3bc82b4 100644 --- a/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx +++ b/apps/dokploy/components/dashboard/application/deployments/show-deployments.tsx @@ -25,6 +25,7 @@ import { import { api, type RouterOutputs } from "@/utils/api"; import { ShowRollbackSettings } from "../rollbacks/show-rollback-settings"; import { CancelQueues } from "./cancel-queues"; +import { KillBuild } from "./kill-build"; import { RefreshToken } from "./refresh-token"; import { ShowDeployment } from "./show-deployment"; @@ -143,6 +144,9 @@ export const ShowDeployments = ({
+ {(type === "application" || type === "compose") && ( + + )} {(type === "application" || type === "compose") && ( )} diff --git a/apps/dokploy/server/api/routers/application.ts b/apps/dokploy/server/api/routers/application.ts index 006d024c4..c713fd7eb 100644 --- a/apps/dokploy/server/api/routers/application.ts +++ b/apps/dokploy/server/api/routers/application.ts @@ -58,7 +58,11 @@ import { applications, } from "@/server/db/schema"; import type { DeploymentJob } from "@/server/queues/queue-types"; -import { cleanQueuesByApplication, myQueue } from "@/server/queues/queueSetup"; +import { + cleanQueuesByApplication, + killDockerBuild, + myQueue, +} from "@/server/queues/queueSetup"; import { cancelDeployment, deploy } from "@/server/utils/deploy"; import { uploadFileSchema } from "@/utils/schema"; @@ -725,7 +729,21 @@ export const applicationRouter = createTRPCRouter({ } await cleanQueuesByApplication(input.applicationId); }), - + killBuild: protectedProcedure + .input(apiFindOneApplication) + .mutation(async ({ input, ctx }) => { + const application = await findApplicationById(input.applicationId); + if ( + application.environment.project.organizationId !== + ctx.session.activeOrganizationId + ) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You are not authorized to kill this build", + }); + } + await killDockerBuild("application", application.serverId); + }), readTraefikConfig: protectedProcedure .input(apiFindOneApplication) .query(async ({ input, ctx }) => { diff --git a/apps/dokploy/server/api/routers/compose.ts b/apps/dokploy/server/api/routers/compose.ts index 026b6e8ad..e233dc6ca 100644 --- a/apps/dokploy/server/api/routers/compose.ts +++ b/apps/dokploy/server/api/routers/compose.ts @@ -59,7 +59,11 @@ import { compose as composeTable, } from "@/server/db/schema"; import type { DeploymentJob } from "@/server/queues/queue-types"; -import { cleanQueuesByCompose, myQueue } from "@/server/queues/queueSetup"; +import { + cleanQueuesByCompose, + killDockerBuild, + myQueue, +} from "@/server/queues/queueSetup"; import { cancelDeployment, deploy } from "@/server/utils/deploy"; import { generatePassword } from "@/templates/utils"; import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc"; @@ -248,6 +252,21 @@ export const composeRouter = createTRPCRouter({ await cleanQueuesByCompose(input.composeId); return { success: true, message: "Queues cleaned successfully" }; }), + killBuild: protectedProcedure + .input(apiFindCompose) + .mutation(async ({ input, ctx }) => { + const compose = await findComposeById(input.composeId); + if ( + compose.environment.project.organizationId !== + ctx.session.activeOrganizationId + ) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You are not authorized to kill this build", + }); + } + await killDockerBuild("compose", compose.serverId); + }), loadServices: protectedProcedure .input(apiFetchServices) diff --git a/apps/dokploy/server/queues/queueSetup.ts b/apps/dokploy/server/queues/queueSetup.ts index 1577273c8..351f5d1c0 100644 --- a/apps/dokploy/server/queues/queueSetup.ts +++ b/apps/dokploy/server/queues/queueSetup.ts @@ -1,3 +1,7 @@ +import { + execAsync, + execAsyncRemote, +} from "@dokploy/server/utils/process/execAsync"; import { Queue } from "bullmq"; import { redisConfig } from "./redis-connection"; @@ -41,4 +45,31 @@ export const cleanQueuesByCompose = async (composeId: string) => { } }; +export const killDockerBuild = async ( + type: "application" | "compose", + serverId: string | null, +) => { + try { + if (type === "application") { + const command = `pkill -2 -f "docker build"`; + + if (serverId) { + await execAsyncRemote(serverId, command); + } else { + await execAsync(command); + } + } else if (type === "compose") { + const command = `pkill -2 -f "docker compose"`; + + if (serverId) { + await execAsyncRemote(serverId, command); + } else { + await execAsync(command); + } + } + } catch (error) { + console.error(error); + } +}; + export { myQueue }; From 96dff0c1bb14bc903616537c467280af72e91596 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Wed, 19 Nov 2025 02:34:05 -0600 Subject: [PATCH 3/3] chore: bump version to v0.25.8 in package.json --- apps/dokploy/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index 1b33df019..070a0d6a4 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -1,6 +1,6 @@ { "name": "dokploy", - "version": "v0.25.7", + "version": "v0.25.8", "private": true, "license": "Apache-2.0", "type": "module",