From 0fb67ced5df0cd2d3cdf4482818dc00f10f17680 Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 26 Jan 2025 18:59:27 -0600 Subject: [PATCH 1/2] fix: remove cron jobs after delete service --- .../dashboard/project/add-database.tsx | 18 ++++++++++----- apps/dokploy/server/api/routers/mariadb.ts | 4 ++++ apps/dokploy/server/api/routers/mongo.ts | 4 ++++ apps/dokploy/server/api/routers/mysql.ts | 4 ++++ apps/dokploy/server/api/routers/postgres.ts | 5 ++++ apps/dokploy/server/api/routers/redis.ts | 1 - apps/dokploy/server/utils/backup.ts | 23 +++++++++++++++++++ packages/server/src/services/backup.ts | 21 ++++++++++++++++- 8 files changed, 72 insertions(+), 8 deletions(-) diff --git a/apps/dokploy/components/dashboard/project/add-database.tsx b/apps/dokploy/components/dashboard/project/add-database.tsx index fc86d253..2ba3eb6b 100644 --- a/apps/dokploy/components/dashboard/project/add-database.tsx +++ b/apps/dokploy/components/dashboard/project/add-database.tsx @@ -89,7 +89,7 @@ const mySchema = z.discriminatedUnion("type", [ z .object({ type: z.literal("postgres"), - databaseName: z.string().min(1, "Database name required"), + databaseName: z.string().default("postgres"), databaseUser: z.string().default("postgres"), }) .merge(baseDatabaseSchema), @@ -110,7 +110,10 @@ const mySchema = z.discriminatedUnion("type", [ type: z.literal("mysql"), databaseRootPassword: z.string().default(""), databaseUser: z.string().default("mysql"), - databaseName: z.string().min(1, "Database name required"), + databaseName: z + .string() + .min(1, "Database name required") + .default("mysql"), }) .merge(baseDatabaseSchema), z @@ -119,7 +122,10 @@ const mySchema = z.discriminatedUnion("type", [ dockerImage: z.string().default("mariadb:4"), databaseRootPassword: z.string().default(""), databaseUser: z.string().default("mariadb"), - databaseName: z.string().min(1, "Database name required"), + databaseName: z + .string() + .min(1, "Database name required") + .default("mariadb"), }) .merge(baseDatabaseSchema), ]); @@ -206,7 +212,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => { promise = postgresMutation.mutateAsync({ ...commonParams, databasePassword: data.databasePassword, - databaseName: data.databaseName, + databaseName: data.databaseName || "postgres", databaseUser: data.databaseUser || databasesUserDefaultPlaceholder[data.type], @@ -233,7 +239,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => { ...commonParams, databasePassword: data.databasePassword, databaseRootPassword: data.databaseRootPassword, - databaseName: data.databaseName, + databaseName: data.databaseName || "mariadb", databaseUser: data.databaseUser || databasesUserDefaultPlaceholder[data.type], serverId: data.serverId, @@ -242,7 +248,7 @@ export const AddDatabase = ({ projectId, projectName }: Props) => { promise = mysqlMutation.mutateAsync({ ...commonParams, databasePassword: data.databasePassword, - databaseName: data.databaseName, + databaseName: data.databaseName || "mysql", databaseUser: data.databaseUser || databasesUserDefaultPlaceholder[data.type], databaseRootPassword: data.databaseRootPassword, diff --git a/apps/dokploy/server/api/routers/mariadb.ts b/apps/dokploy/server/api/routers/mariadb.ts index 09f4d675..6e85d274 100644 --- a/apps/dokploy/server/api/routers/mariadb.ts +++ b/apps/dokploy/server/api/routers/mariadb.ts @@ -9,6 +9,7 @@ import { apiSaveExternalPortMariaDB, apiUpdateMariaDB, } from "@/server/db/schema"; +import { cancelJobs } from "@/server/utils/backup"; import { IS_CLOUD, addNewService, @@ -16,6 +17,7 @@ import { createMariadb, createMount, deployMariadb, + findBackupsByDbId, findMariadbById, findProjectById, findServerById, @@ -211,8 +213,10 @@ export const mariadbRouter = createTRPCRouter({ }); } + const backups = await findBackupsByDbId(input.mariadbId, "mariadb"); const cleanupOperations = [ async () => await removeService(mongo?.appName, mongo.serverId), + async () => await cancelJobs(backups), async () => await removeMariadbById(input.mariadbId), ]; diff --git a/apps/dokploy/server/api/routers/mongo.ts b/apps/dokploy/server/api/routers/mongo.ts index b114b8d8..2bca3ec5 100644 --- a/apps/dokploy/server/api/routers/mongo.ts +++ b/apps/dokploy/server/api/routers/mongo.ts @@ -9,6 +9,7 @@ import { apiSaveExternalPortMongo, apiUpdateMongo, } from "@/server/db/schema"; +import { cancelJobs } from "@/server/utils/backup"; import { IS_CLOUD, addNewService, @@ -16,6 +17,7 @@ import { createMongo, createMount, deployMongo, + findBackupsByDbId, findMongoById, findProjectById, removeMongoById, @@ -252,9 +254,11 @@ export const mongoRouter = createTRPCRouter({ message: "You are not authorized to delete this mongo", }); } + const backups = await findBackupsByDbId(input.mongoId, "mongo"); const cleanupOperations = [ async () => await removeService(mongo?.appName, mongo.serverId), + async () => await cancelJobs(backups), async () => await removeMongoById(input.mongoId), ]; diff --git a/apps/dokploy/server/api/routers/mysql.ts b/apps/dokploy/server/api/routers/mysql.ts index 44d2537a..7022d7e1 100644 --- a/apps/dokploy/server/api/routers/mysql.ts +++ b/apps/dokploy/server/api/routers/mysql.ts @@ -19,6 +19,7 @@ import { createMount, createMysql, deployMySql, + findBackupsByDbId, findMySqlById, findProjectById, removeMySqlById, @@ -30,6 +31,7 @@ import { updateMySqlById, } from "@dokploy/server"; import { observable } from "@trpc/server/observable"; +import { cancelJobs } from "@/server/utils/backup"; export const mysqlRouter = createTRPCRouter({ create: protectedProcedure @@ -249,8 +251,10 @@ export const mysqlRouter = createTRPCRouter({ }); } + const backups = await findBackupsByDbId(input.mysqlId, "mysql"); const cleanupOperations = [ async () => await removeService(mongo?.appName, mongo.serverId), + async () => await cancelJobs(backups), async () => await removeMySqlById(input.mysqlId), ]; diff --git a/apps/dokploy/server/api/routers/postgres.ts b/apps/dokploy/server/api/routers/postgres.ts index 7d178943..c7ac462f 100644 --- a/apps/dokploy/server/api/routers/postgres.ts +++ b/apps/dokploy/server/api/routers/postgres.ts @@ -21,6 +21,7 @@ import { createMount, createPostgres, deployPostgres, + findBackupsByDbId, findPostgresById, findProjectById, removePostgresById, @@ -34,6 +35,7 @@ import { import { TRPCError } from "@trpc/server"; import { observable } from "@trpc/server/observable"; import { z } from "zod"; +import { cancelJobs } from "@/server/utils/backup"; const ee = new EventEmitter(); @@ -231,8 +233,11 @@ export const postgresRouter = createTRPCRouter({ }); } + const backups = await findBackupsByDbId(input.postgresId, "postgres"); + const cleanupOperations = [ removeService(postgres.appName, postgres.serverId), + cancelJobs(backups), removePostgresById(input.postgresId), ]; diff --git a/apps/dokploy/server/api/routers/redis.ts b/apps/dokploy/server/api/routers/redis.ts index 5883e50b..967fb51a 100644 --- a/apps/dokploy/server/api/routers/redis.ts +++ b/apps/dokploy/server/api/routers/redis.ts @@ -244,7 +244,6 @@ export const redisRouter = createTRPCRouter({ message: "You are not authorized to delete this Redis", }); } - const cleanupOperations = [ async () => await removeService(redis?.appName, redis.serverId), async () => await removeRedisById(input.redisId), diff --git a/apps/dokploy/server/utils/backup.ts b/apps/dokploy/server/utils/backup.ts index a178063f..2f141971 100644 --- a/apps/dokploy/server/utils/backup.ts +++ b/apps/dokploy/server/utils/backup.ts @@ -1,3 +1,10 @@ +import { + type BackupScheduleList, + IS_CLOUD, + removeScheduleBackup, + scheduleBackup, +} from "@dokploy/server/index"; + type QueueJob = | { type: "backup"; @@ -59,3 +66,19 @@ export const updateJob = async (job: QueueJob) => { throw error; } }; + +export const cancelJobs = async (backups: BackupScheduleList) => { + for (const backup of backups) { + if (backup.enabled) { + if (IS_CLOUD) { + await removeJob({ + cronSchedule: backup.schedule, + backupId: backup.backupId, + type: "backup", + }); + } else { + removeScheduleBackup(backup.backupId); + } + } + } +}; diff --git a/packages/server/src/services/backup.ts b/packages/server/src/services/backup.ts index 70e37af4..ef3d0446 100644 --- a/packages/server/src/services/backup.ts +++ b/packages/server/src/services/backup.ts @@ -2,11 +2,13 @@ import { db } from "@dokploy/server/db"; import { type apiCreateBackup, backups } from "@dokploy/server/db/schema"; import { TRPCError } from "@trpc/server"; import { eq } from "drizzle-orm"; +import { IS_CLOUD } from "../constants"; +import { removeScheduleBackup, scheduleBackup } from "../utils/backups/utils"; export type Backup = typeof backups.$inferSelect; export type BackupSchedule = Awaited>; - +export type BackupScheduleList = Awaited>; export const createBackup = async (input: typeof apiCreateBackup._type) => { const newBackup = await db .insert(backups) @@ -69,3 +71,20 @@ export const removeBackupById = async (backupId: string) => { return result[0]; }; + +export const findBackupsByDbId = async ( + id: string, + type: "postgres" | "mysql" | "mariadb" | "mongo", +) => { + const result = await db.query.backups.findMany({ + where: eq(backups[`${type}Id`], id), + with: { + postgres: true, + mysql: true, + mariadb: true, + mongo: true, + destination: true, + }, + }); + return result || []; +}; From 24327139b829857a666dea36d80ead978a250a2b Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Sun, 26 Jan 2025 19:00:58 -0600 Subject: [PATCH 2/2] refactor: make optional field name --- .../components/dashboard/project/add-database.tsx | 10 ++-------- apps/dokploy/server/api/routers/mysql.ts | 2 +- apps/dokploy/server/api/routers/postgres.ts | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/apps/dokploy/components/dashboard/project/add-database.tsx b/apps/dokploy/components/dashboard/project/add-database.tsx index 2ba3eb6b..1ca0d6a5 100644 --- a/apps/dokploy/components/dashboard/project/add-database.tsx +++ b/apps/dokploy/components/dashboard/project/add-database.tsx @@ -110,10 +110,7 @@ const mySchema = z.discriminatedUnion("type", [ type: z.literal("mysql"), databaseRootPassword: z.string().default(""), databaseUser: z.string().default("mysql"), - databaseName: z - .string() - .min(1, "Database name required") - .default("mysql"), + databaseName: z.string().default("mysql"), }) .merge(baseDatabaseSchema), z @@ -122,10 +119,7 @@ const mySchema = z.discriminatedUnion("type", [ dockerImage: z.string().default("mariadb:4"), databaseRootPassword: z.string().default(""), databaseUser: z.string().default("mariadb"), - databaseName: z - .string() - .min(1, "Database name required") - .default("mariadb"), + databaseName: z.string().default("mariadb"), }) .merge(baseDatabaseSchema), ]); diff --git a/apps/dokploy/server/api/routers/mysql.ts b/apps/dokploy/server/api/routers/mysql.ts index 7022d7e1..7ebf4623 100644 --- a/apps/dokploy/server/api/routers/mysql.ts +++ b/apps/dokploy/server/api/routers/mysql.ts @@ -12,6 +12,7 @@ import { import { TRPCError } from "@trpc/server"; +import { cancelJobs } from "@/server/utils/backup"; import { IS_CLOUD, addNewService, @@ -31,7 +32,6 @@ import { updateMySqlById, } from "@dokploy/server"; import { observable } from "@trpc/server/observable"; -import { cancelJobs } from "@/server/utils/backup"; export const mysqlRouter = createTRPCRouter({ create: protectedProcedure diff --git a/apps/dokploy/server/api/routers/postgres.ts b/apps/dokploy/server/api/routers/postgres.ts index c7ac462f..92603a61 100644 --- a/apps/dokploy/server/api/routers/postgres.ts +++ b/apps/dokploy/server/api/routers/postgres.ts @@ -14,6 +14,7 @@ import { apiSaveExternalPortPostgres, apiUpdatePostgres, } from "@/server/db/schema"; +import { cancelJobs } from "@/server/utils/backup"; import { IS_CLOUD, addNewService, @@ -35,7 +36,6 @@ import { import { TRPCError } from "@trpc/server"; import { observable } from "@trpc/server/observable"; import { z } from "zod"; -import { cancelJobs } from "@/server/utils/backup"; const ee = new EventEmitter();