mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
feat: extend volume backup functionality with scheduling and management
- Added support for volume backup jobs in the scheduling and removal processes. - Enhanced job management to include volume backups in the job queue. - Updated schema to accommodate volume backup data structure. - Implemented initialization of volume backup jobs based on server status, improving backup management.
This commit is contained in:
@@ -61,6 +61,12 @@ app.post("/update-backup", zValidator("json", jobQueueSchema), async (c) => {
|
||||
type: "schedule",
|
||||
cronSchedule: job.pattern,
|
||||
});
|
||||
} else if (data.type === "volume-backup") {
|
||||
result = await removeJob({
|
||||
volumeBackupId: data.volumeBackupId,
|
||||
type: "volume-backup",
|
||||
cronSchedule: job.pattern,
|
||||
});
|
||||
}
|
||||
logger.info({ result }, "Job removed");
|
||||
}
|
||||
|
||||
@@ -42,6 +42,12 @@ export const scheduleJob = (job: QueueJob) => {
|
||||
pattern: job.cronSchedule,
|
||||
},
|
||||
});
|
||||
} else if (job.type === "volume-backup") {
|
||||
jobQueue.add(job.volumeBackupId, job, {
|
||||
repeat: {
|
||||
pattern: job.cronSchedule,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,6 +73,13 @@ export const removeJob = async (data: QueueJob) => {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
if (data.type === "volume-backup") {
|
||||
const { volumeBackupId, cronSchedule } = data;
|
||||
const result = await jobQueue.removeRepeatable(volumeBackupId, {
|
||||
pattern: cronSchedule,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -89,6 +102,10 @@ export const getJobRepeatable = async (
|
||||
const job = repeatableJobs.find((j) => j.name === scheduleId);
|
||||
return job ? job : null;
|
||||
}
|
||||
|
||||
if (data.type === "volume-backup") {
|
||||
const { volumeBackupId } = data;
|
||||
const job = repeatableJobs.find((j) => j.name === volumeBackupId);
|
||||
return job ? job : null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -16,6 +16,11 @@ export const jobQueueSchema = z.discriminatedUnion("type", [
|
||||
type: z.literal("schedule"),
|
||||
scheduleId: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
cronSchedule: z.string(),
|
||||
type: z.literal("volume-backup"),
|
||||
volumeBackupId: z.string(),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type QueueJob = z.infer<typeof jobQueueSchema>;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
findBackupById,
|
||||
findScheduleById,
|
||||
findServerById,
|
||||
findVolumeBackupById,
|
||||
keepLatestNBackups,
|
||||
runCommand,
|
||||
runComposeBackup,
|
||||
@@ -12,9 +13,15 @@ import {
|
||||
runMongoBackup,
|
||||
runMySqlBackup,
|
||||
runPostgresBackup,
|
||||
runVolumeBackup,
|
||||
} from "@dokploy/server";
|
||||
import { db } from "@dokploy/server/dist/db";
|
||||
import { backups, schedules, server } from "@dokploy/server/dist/db/schema";
|
||||
import {
|
||||
backups,
|
||||
schedules,
|
||||
server,
|
||||
volumeBackups,
|
||||
} from "@dokploy/server/dist/db/schema";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { logger } from "./logger.js";
|
||||
import { scheduleJob } from "./queue.js";
|
||||
@@ -93,6 +100,12 @@ export const runJobs = async (job: QueueJob) => {
|
||||
if (schedule.enabled) {
|
||||
await runCommand(schedule.scheduleId);
|
||||
}
|
||||
} else if (job.type === "volume-backup") {
|
||||
const { volumeBackupId } = job;
|
||||
const volumeBackup = await findVolumeBackupById(volumeBackupId);
|
||||
if (volumeBackup.enabled) {
|
||||
await runVolumeBackup(volumeBackupId);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
@@ -184,4 +197,44 @@ export const initializeJobs = async () => {
|
||||
{ Quantity: filteredSchedulesBasedOnServerStatus.length },
|
||||
"Schedules Initialized",
|
||||
);
|
||||
|
||||
const volumeBackupsResult = await db.query.volumeBackups.findMany({
|
||||
where: eq(volumeBackups.enabled, true),
|
||||
with: {
|
||||
application: {
|
||||
with: {
|
||||
server: true,
|
||||
},
|
||||
},
|
||||
compose: {
|
||||
with: {
|
||||
server: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const filteredVolumeBackupsBasedOnServerStatus = volumeBackupsResult.filter(
|
||||
(volumeBackup) => {
|
||||
if (volumeBackup.application) {
|
||||
return volumeBackup.application.server?.serverStatus === "active";
|
||||
}
|
||||
if (volumeBackup.compose) {
|
||||
return volumeBackup.compose.server?.serverStatus === "active";
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
for (const volumeBackup of filteredVolumeBackupsBasedOnServerStatus) {
|
||||
scheduleJob({
|
||||
volumeBackupId: volumeBackup.volumeBackupId,
|
||||
type: "volume-backup",
|
||||
cronSchedule: volumeBackup.cronExpression,
|
||||
});
|
||||
}
|
||||
|
||||
logger.info(
|
||||
{ Quantity: filteredVolumeBackupsBasedOnServerStatus.length },
|
||||
"Volume Backups Initialized",
|
||||
);
|
||||
};
|
||||
|
||||
@@ -63,8 +63,6 @@ export * from "./utils/notifications/utils";
|
||||
export * from "./utils/notifications/docker-cleanup";
|
||||
export * from "./utils/notifications/server-threshold";
|
||||
|
||||
export * from "./utils/volume-backups/index";
|
||||
|
||||
export * from "./utils/builders/index";
|
||||
export * from "./utils/builders/compose";
|
||||
export * from "./utils/builders/docker-file";
|
||||
@@ -135,5 +133,6 @@ export {
|
||||
|
||||
export * from "./utils/schedules/utils";
|
||||
export * from "./utils/schedules/index";
|
||||
export * from "./utils/volume-backups/index";
|
||||
|
||||
export * from "./lib/logger";
|
||||
|
||||
Reference in New Issue
Block a user