diff --git a/apps/dokploy/components/dashboard/project/add-database.tsx b/apps/dokploy/components/dashboard/project/add-database.tsx index fc86d253..1ca0d6a5 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,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"), + databaseName: z.string().default("mysql"), }) .merge(baseDatabaseSchema), z @@ -119,7 +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"), + databaseName: z.string().default("mariadb"), }) .merge(baseDatabaseSchema), ]); @@ -206,7 +206,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 +233,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 +242,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..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, @@ -19,6 +20,7 @@ import { createMount, createMysql, deployMySql, + findBackupsByDbId, findMySqlById, findProjectById, removeMySqlById, @@ -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..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, @@ -21,6 +22,7 @@ import { createMount, createPostgres, deployPostgres, + findBackupsByDbId, findPostgresById, findProjectById, removePostgresById, @@ -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 || []; +};