From 2b44a0fc7f49c92ea3f3bc8440c5343d0046246d Mon Sep 17 00:00:00 2001 From: irwanda Date: Sat, 6 Jun 2026 13:06:27 +0700 Subject: [PATCH 1/3] fix: clear old deployments keeping only active deployment record and logs --- .../dokploy/server/api/routers/application.ts | 2 +- apps/dokploy/server/api/routers/compose.ts | 2 +- packages/server/src/services/deployment.ts | 42 ++++++++++++++----- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/apps/dokploy/server/api/routers/application.ts b/apps/dokploy/server/api/routers/application.ts index c7b1f8642f..52f209df57 100644 --- a/apps/dokploy/server/api/routers/application.ts +++ b/apps/dokploy/server/api/routers/application.ts @@ -754,7 +754,7 @@ export const applicationRouter = createTRPCRouter({ deployment: ["create"], }); const application = await findApplicationById(input.applicationId); - await clearOldDeployments(application.appName, application.serverId); + await clearOldDeployments(application.applicationId, "application", application.serverId); await audit(ctx, { action: "delete", resourceType: "application", diff --git a/apps/dokploy/server/api/routers/compose.ts b/apps/dokploy/server/api/routers/compose.ts index 51e257ce65..f76542b1d1 100644 --- a/apps/dokploy/server/api/routers/compose.ts +++ b/apps/dokploy/server/api/routers/compose.ts @@ -298,7 +298,7 @@ export const composeRouter = createTRPCRouter({ deployment: ["create"], }); const compose = await findComposeById(input.composeId); - await clearOldDeployments(compose.appName, compose.serverId); + await clearOldDeployments(compose.composeId, "compose", compose.serverId); await audit(ctx, { action: "update", resourceType: "compose", diff --git a/packages/server/src/services/deployment.ts b/packages/server/src/services/deployment.ts index a5ff577791..8b3621fbe2 100644 --- a/packages/server/src/services/deployment.ts +++ b/packages/server/src/services/deployment.ts @@ -1035,17 +1035,37 @@ export const findAllDeploymentsByServerId = async (serverId: string) => { }; export const clearOldDeployments = async ( - appName: string, + id: string, + type: "application" | "compose", serverId: string | null, ) => { - const { LOGS_PATH } = paths(!!serverId); - const folder = path.join(LOGS_PATH, appName); - const command = ` - rm -rf ${folder}; - `; - if (serverId) { - await execAsyncRemote(serverId, command); - } else { - await execAsync(command); + const deploymentsList = await db.query.deployments.findMany({ + where: eq(deployments[`${type}Id`], id), + orderBy: desc(deployments.createdAt), + }); + + const currentDeployment = + deploymentsList.find((d) => d.status === "done") ?? deploymentsList[0]; + + if (!currentDeployment || deploymentsList.length <= 1) { + return; } -}; + + const deploymentsToDelete = deploymentsList.filter( + (d) => d.deploymentId !== currentDeployment.deploymentId, + ); + + for (const oldDeployment of deploymentsToDelete) { + try { + if (oldDeployment.rollbackId) { + await removeRollbackById(oldDeployment.rollbackId); + } + await removeDeployment(oldDeployment.deploymentId); + } catch (err) { + console.error( + `Failed to remove deployment ${oldDeployment.deploymentId} during cleanup:`, + err, + ); + } + } +}; \ No newline at end of file From 74843662e0e0f12130b442fe91f0c0da364e0212 Mon Sep 17 00:00:00 2001 From: irwanda Date: Sat, 6 Jun 2026 14:35:49 +0700 Subject: [PATCH 2/3] feat: implement remote log file cleanup during deployment deletion --- packages/server/src/services/deployment.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/server/src/services/deployment.ts b/packages/server/src/services/deployment.ts index 8b3621fbe2..5c544dd0f3 100644 --- a/packages/server/src/services/deployment.ts +++ b/packages/server/src/services/deployment.ts @@ -1055,11 +1055,21 @@ export const clearOldDeployments = async ( (d) => d.deploymentId !== currentDeployment.deploymentId, ); + const remoteLogCommands: string[] = []; + for (const oldDeployment of deploymentsToDelete) { try { if (oldDeployment.rollbackId) { await removeRollbackById(oldDeployment.rollbackId); } + + const logPath = path.join(oldDeployment.logPath); + const hasLogPath = logPath && logPath !== "."; + + if (serverId) { + if (hasLogPath) remoteLogCommands.push(`rm -f "${logPath}"`); + } + await removeDeployment(oldDeployment.deploymentId); } catch (err) { console.error( @@ -1068,4 +1078,8 @@ export const clearOldDeployments = async ( ); } } -}; \ No newline at end of file + + if (serverId && remoteLogCommands.length > 0) { + await execAsyncRemote(serverId, remoteLogCommands.join(";")); + } +}; From 18d28844695e7956ee9a003aa3eebce024c85e5b Mon Sep 17 00:00:00 2001 From: irwanda Date: Sun, 7 Jun 2026 08:57:20 +0700 Subject: [PATCH 3/3] refactor: remove manual log deletion from clearOldDeployments --- apps/dokploy/server/api/routers/application.ts | 2 +- apps/dokploy/server/api/routers/compose.ts | 2 +- packages/server/src/services/deployment.ts | 16 +--------------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/apps/dokploy/server/api/routers/application.ts b/apps/dokploy/server/api/routers/application.ts index 52f209df57..6d79fada07 100644 --- a/apps/dokploy/server/api/routers/application.ts +++ b/apps/dokploy/server/api/routers/application.ts @@ -754,7 +754,7 @@ export const applicationRouter = createTRPCRouter({ deployment: ["create"], }); const application = await findApplicationById(input.applicationId); - await clearOldDeployments(application.applicationId, "application", application.serverId); + await clearOldDeployments(application.applicationId, "application"); await audit(ctx, { action: "delete", resourceType: "application", diff --git a/apps/dokploy/server/api/routers/compose.ts b/apps/dokploy/server/api/routers/compose.ts index f76542b1d1..fc34fb4be1 100644 --- a/apps/dokploy/server/api/routers/compose.ts +++ b/apps/dokploy/server/api/routers/compose.ts @@ -298,7 +298,7 @@ export const composeRouter = createTRPCRouter({ deployment: ["create"], }); const compose = await findComposeById(input.composeId); - await clearOldDeployments(compose.composeId, "compose", compose.serverId); + await clearOldDeployments(compose.composeId, "compose"); await audit(ctx, { action: "update", resourceType: "compose", diff --git a/packages/server/src/services/deployment.ts b/packages/server/src/services/deployment.ts index 5c544dd0f3..362d329dd2 100644 --- a/packages/server/src/services/deployment.ts +++ b/packages/server/src/services/deployment.ts @@ -1036,8 +1036,7 @@ export const findAllDeploymentsByServerId = async (serverId: string) => { export const clearOldDeployments = async ( id: string, - type: "application" | "compose", - serverId: string | null, + type: "application" | "compose" ) => { const deploymentsList = await db.query.deployments.findMany({ where: eq(deployments[`${type}Id`], id), @@ -1055,21 +1054,12 @@ export const clearOldDeployments = async ( (d) => d.deploymentId !== currentDeployment.deploymentId, ); - const remoteLogCommands: string[] = []; - for (const oldDeployment of deploymentsToDelete) { try { if (oldDeployment.rollbackId) { await removeRollbackById(oldDeployment.rollbackId); } - const logPath = path.join(oldDeployment.logPath); - const hasLogPath = logPath && logPath !== "."; - - if (serverId) { - if (hasLogPath) remoteLogCommands.push(`rm -f "${logPath}"`); - } - await removeDeployment(oldDeployment.deploymentId); } catch (err) { console.error( @@ -1078,8 +1068,4 @@ export const clearOldDeployments = async ( ); } } - - if (serverId && remoteLogCommands.length > 0) { - await execAsyncRemote(serverId, remoteLogCommands.join(";")); - } };