diff --git a/apps/dokploy/package.json b/apps/dokploy/package.json index c796ce3a7..c1d00d67c 100644 --- a/apps/dokploy/package.json +++ b/apps/dokploy/package.json @@ -99,7 +99,7 @@ "better-auth": "1.4.18", "bl": "6.0.11", "boxen": "^7.1.1", - "bullmq": "5.4.2", + "bullmq": "5.67.3", "shell-quote": "^1.8.1", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/apps/dokploy/server/api/routers/application.ts b/apps/dokploy/server/api/routers/application.ts index b494fdf36..9240a1cb3 100644 --- a/apps/dokploy/server/api/routers/application.ts +++ b/apps/dokploy/server/api/routers/application.ts @@ -57,9 +57,11 @@ import { apiUpdateApplication, applications, } from "@/server/db/schema"; +import { deploymentWorker } from "@/server/queues/deployments-queue"; import type { DeploymentJob } from "@/server/queues/queue-types"; import { cleanQueuesByApplication, + getJobsByApplicationId, killDockerBuild, myQueue, } from "@/server/queues/queueSetup"; @@ -240,6 +242,15 @@ export const applicationRouter = createTRPCRouter({ .where(eq(applications.applicationId, input.applicationId)) .returning(); + if (!IS_CLOUD) { + const queueJobs = await getJobsByApplicationId(input.applicationId); + for (const job of queueJobs) { + if (job.id) { + deploymentWorker.cancelJob(job.id, "User requested cancellation"); + } + } + } + const cleanupOperations = [ async () => await deleteAllMiddlewares(application), async () => await removeDeployments(application), diff --git a/apps/dokploy/server/api/routers/compose.ts b/apps/dokploy/server/api/routers/compose.ts index 9354988a8..01f9c8b04 100644 --- a/apps/dokploy/server/api/routers/compose.ts +++ b/apps/dokploy/server/api/routers/compose.ts @@ -58,9 +58,11 @@ import { apiUpdateCompose, compose as composeTable, } from "@/server/db/schema"; +import { deploymentWorker } from "@/server/queues/deployments-queue"; import type { DeploymentJob } from "@/server/queues/queue-types"; import { cleanQueuesByCompose, + getJobsByComposeId, killDockerBuild, myQueue, } from "@/server/queues/queueSetup"; @@ -222,6 +224,15 @@ export const composeRouter = createTRPCRouter({ .where(eq(composeTable.composeId, input.composeId)) .returning(); + if (!IS_CLOUD) { + const queueJobs = await getJobsByComposeId(input.composeId); + for (const job of queueJobs) { + if (job.id) { + deploymentWorker.cancelJob(job.id, "User requested cancellation"); + } + } + } + const cleanupOperations = [ async () => await removeCompose(composeResult, input.deleteVolumes), async () => await removeDeploymentsByComposeId(composeResult), diff --git a/apps/dokploy/server/queues/queueSetup.ts b/apps/dokploy/server/queues/queueSetup.ts index 351f5d1c0..d1a0acf58 100644 --- a/apps/dokploy/server/queues/queueSetup.ts +++ b/apps/dokploy/server/queues/queueSetup.ts @@ -9,6 +9,16 @@ const myQueue = new Queue("deployments", { connection: redisConfig, }); +export const getJobsByApplicationId = async (applicationId: string) => { + const jobs = await myQueue.getJobs(); + return jobs.filter((job) => job?.data?.applicationId === applicationId); +}; + +export const getJobsByComposeId = async (composeId: string) => { + const jobs = await myQueue.getJobs(); + return jobs.filter((job) => job?.data?.composeId === composeId); +}; + process.on("SIGTERM", () => { myQueue.close(); process.exit(0); diff --git a/apps/schedules/package.json b/apps/schedules/package.json index b5c7bdac1..620b73f92 100644 --- a/apps/schedules/package.json +++ b/apps/schedules/package.json @@ -11,7 +11,7 @@ "@dokploy/server": "workspace:*", "@hono/node-server": "^1.14.3", "@hono/zod-validator": "0.3.0", - "bullmq": "5.4.2", + "bullmq": "5.67.3", "dotenv": "^16.4.5", "drizzle-orm": "^0.41.0", "hono": "^4.11.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e9b25d1e..d6aeee61b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -272,8 +272,8 @@ importers: specifier: ^7.1.1 version: 7.1.1 bullmq: - specifier: 5.4.2 - version: 5.4.2 + specifier: 5.67.3 + version: 5.67.3 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -540,8 +540,8 @@ importers: specifier: 0.3.0 version: 0.3.0(hono@4.11.7)(zod@3.25.32) bullmq: - specifier: 5.4.2 - version: 5.4.2 + specifier: 5.67.3 + version: 5.67.3 dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -2137,6 +2137,9 @@ packages: '@ioredis/commands@1.2.0': resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + '@ioredis/commands@1.5.0': + resolution: {integrity: sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -4800,8 +4803,8 @@ packages: resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} engines: {node: '>=10.0.0'} - bullmq@5.4.2: - resolution: {integrity: sha512-dkR/KGUw18miLe3QWtvSlmGvEe08aZF+w1jZyqEHMWFW3RP4162qp6OGud0/QCAOjusiRI8UOxUhbnortPY+rA==} + bullmq@5.67.3: + resolution: {integrity: sha512-eeQobOJn8M0Rj8tcZCVFLrimZgJQallJH1JpclOoyut2nDNkDwTEPMVcZzLeSR2fGeIVbfJTjU96F563Qkge5A==} bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} @@ -5966,6 +5969,10 @@ packages: resolution: {integrity: sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==} engines: {node: '>=12.22.0'} + ioredis@5.9.2: + resolution: {integrity: sha512-tAAg/72/VxOUW7RQSX1pIxJVucYKcjFjfvj60L57jrZpYCHC3XN0WCQ3sNYL4Gmvv+7GPvTAjc+KSdeNuE8oWQ==} + engines: {node: '>=12.22.0'} + ip-regex@5.0.0: resolution: {integrity: sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6531,8 +6538,8 @@ packages: resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} hasBin: true - msgpackr@1.11.4: - resolution: {integrity: sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg==} + msgpackr@1.11.5: + resolution: {integrity: sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==} mylas@2.1.13: resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==} @@ -8013,6 +8020,10 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -9409,6 +9420,8 @@ snapshots: '@ioredis/commands@1.2.0': {} + '@ioredis/commands@1.5.0': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -12583,16 +12596,15 @@ snapshots: buildcheck@0.0.6: optional: true - bullmq@5.4.2: + bullmq@5.67.3: dependencies: cron-parser: 4.9.0 - ioredis: 5.4.1 - lodash: 4.17.21 - msgpackr: 1.11.4 + ioredis: 5.9.2 + msgpackr: 1.11.5 node-abort-controller: 3.1.1 semver: 7.7.3 tslib: 2.8.1 - uuid: 9.0.1 + uuid: 11.1.0 transitivePeerDependencies: - supports-color @@ -13796,6 +13808,20 @@ snapshots: transitivePeerDependencies: - supports-color + ioredis@5.9.2: + dependencies: + '@ioredis/commands': 1.5.0 + cluster-key-slot: 1.1.2 + debug: 4.4.1 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + ip-regex@5.0.0: {} iron-webcrypto@1.2.1: {} @@ -14484,7 +14510,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 optional: true - msgpackr@1.11.4: + msgpackr@1.11.5: optionalDependencies: msgpackr-extract: 3.0.3 @@ -16106,6 +16132,8 @@ snapshots: uuid@10.0.0: {} + uuid@11.1.0: {} + uuid@8.3.2: {} uuid@9.0.1: {}