mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-21 15:15:30 +02:00
feat: enhance volume backup functionality and schema
- Added support for volume backups in the deployment management interface by introducing a new volumeBackupId field in the deployment schema. - Updated the volume backup schema to include relationships with deployments, allowing for better management and tracking of volume backups. - Enhanced API routes to include application data when querying volume backups, improving the data returned for related entities. - Updated UI components to reflect the new volume backup features and ensure seamless integration with existing functionalities.
This commit is contained in:
@@ -14,7 +14,8 @@ interface Props {
|
||||
| "schedule"
|
||||
| "server"
|
||||
| "backup"
|
||||
| "previewDeployment";
|
||||
| "previewDeployment"
|
||||
| "volumeBackup";
|
||||
serverId?: string;
|
||||
refreshToken?: string;
|
||||
children?: React.ReactNode;
|
||||
|
||||
@@ -27,7 +27,8 @@ interface Props {
|
||||
| "schedule"
|
||||
| "server"
|
||||
| "backup"
|
||||
| "previewDeployment";
|
||||
| "previewDeployment"
|
||||
| "volumeBackup";
|
||||
refreshToken?: string;
|
||||
serverId?: string;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,17 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { api } from "@/utils/api";
|
||||
import { Clock, DatabaseBackup, Loader2, Play, Trash2 } from "lucide-react";
|
||||
import {
|
||||
ClipboardList,
|
||||
Clock,
|
||||
DatabaseBackup,
|
||||
Loader2,
|
||||
Play,
|
||||
Trash2,
|
||||
} from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { HandleVolumeBackups } from "./handle-volume-backups";
|
||||
import { ShowDeploymentsModal } from "../deployments/show-deployments-modal";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
@@ -86,6 +94,14 @@ export const ShowVolumeBackups = ({
|
||||
) : volumeBackups && volumeBackups.length > 0 ? (
|
||||
<div className="grid xl:grid-cols-2 gap-4 grid-cols-1 h-full">
|
||||
{volumeBackups.map((volumeBackup) => {
|
||||
const serverId =
|
||||
volumeBackup.application?.serverId ||
|
||||
volumeBackup.postgres?.serverId ||
|
||||
volumeBackup.mysql?.serverId ||
|
||||
volumeBackup.mariadb?.serverId ||
|
||||
volumeBackup.mongo?.serverId ||
|
||||
volumeBackup.redis?.serverId ||
|
||||
volumeBackup.compose?.serverId;
|
||||
return (
|
||||
<div
|
||||
key={volumeBackup.volumeBackupId}
|
||||
@@ -116,34 +132,20 @@ export const ShowVolumeBackups = ({
|
||||
>
|
||||
Cron: {volumeBackup.cronExpression}
|
||||
</Badge>
|
||||
{/* {schedule.scheduleType !== "server" &&
|
||||
schedule.scheduleType !== "dokploy-server" && (
|
||||
<>
|
||||
<span className="text-xs text-muted-foreground/50">
|
||||
•
|
||||
</span>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="font-mono text-[10px] bg-transparent"
|
||||
>
|
||||
{schedule.shellType}
|
||||
</Badge>
|
||||
</>
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1.5">
|
||||
{/* <ShowDeploymentsModal
|
||||
id={schedule.scheduleId}
|
||||
type="schedule"
|
||||
<ShowDeploymentsModal
|
||||
id={volumeBackup.volumeBackupId}
|
||||
type="volumeBackup"
|
||||
serverId={serverId || undefined}
|
||||
>
|
||||
<Button variant="ghost" size="icon">
|
||||
<ClipboardList className="size-4 transition-colors " />
|
||||
</Button>
|
||||
</ShowDeploymentsModal> */}
|
||||
</ShowDeploymentsModal>
|
||||
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<Tooltip>
|
||||
|
||||
2
apps/dokploy/drizzle/0106_furry_gargoyle.sql
Normal file
2
apps/dokploy/drizzle/0106_furry_gargoyle.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "deployment" ADD COLUMN "volumeBackupId" text;--> statement-breakpoint
|
||||
ALTER TABLE "deployment" ADD CONSTRAINT "deployment_volumeBackupId_volume_backup_volumeBackupId_fk" FOREIGN KEY ("volumeBackupId") REFERENCES "public"."volume_backup"("volumeBackupId") ON DELETE cascade ON UPDATE no action;
|
||||
6086
apps/dokploy/drizzle/meta/0106_snapshot.json
Normal file
6086
apps/dokploy/drizzle/meta/0106_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -743,6 +743,13 @@
|
||||
"when": 1751259917258,
|
||||
"tag": "0105_unknown_firelord",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 106,
|
||||
"version": "7",
|
||||
"when": 1751260111986,
|
||||
"tag": "0106_furry_gargoyle",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -34,6 +34,15 @@ export const volumeBackupsRouter = createTRPCRouter({
|
||||
.query(async ({ input }) => {
|
||||
return await db.query.volumeBackups.findMany({
|
||||
where: eq(volumeBackups[`${input.volumeBackupType}Id`], input.id),
|
||||
with: {
|
||||
application: true,
|
||||
postgres: true,
|
||||
mysql: true,
|
||||
mariadb: true,
|
||||
mongo: true,
|
||||
redis: true,
|
||||
compose: true,
|
||||
},
|
||||
});
|
||||
}),
|
||||
create: protectedProcedure
|
||||
|
||||
@@ -16,6 +16,7 @@ import { previewDeployments } from "./preview-deployments";
|
||||
import { schedules } from "./schedule";
|
||||
import { server } from "./server";
|
||||
import { rollbacks } from "./rollbacks";
|
||||
import { volumeBackups } from "./volume-backups";
|
||||
export const deploymentStatus = pgEnum("deploymentStatus", [
|
||||
"running",
|
||||
"done",
|
||||
@@ -64,6 +65,10 @@ export const deployments = pgTable("deployment", {
|
||||
(): AnyPgColumn => rollbacks.rollbackId,
|
||||
{ onDelete: "cascade" },
|
||||
),
|
||||
volumeBackupId: text("volumeBackupId").references(
|
||||
(): AnyPgColumn => volumeBackups.volumeBackupId,
|
||||
{ onDelete: "cascade" },
|
||||
),
|
||||
});
|
||||
|
||||
export const deploymentsRelations = relations(deployments, ({ one }) => ({
|
||||
@@ -95,6 +100,10 @@ export const deploymentsRelations = relations(deployments, ({ one }) => ({
|
||||
fields: [deployments.deploymentId],
|
||||
references: [rollbacks.deploymentId],
|
||||
}),
|
||||
volumeBackup: one(volumeBackups, {
|
||||
fields: [deployments.volumeBackupId],
|
||||
references: [volumeBackups.volumeBackupId],
|
||||
}),
|
||||
}));
|
||||
|
||||
const schema = createInsertSchema(deployments, {
|
||||
@@ -216,6 +225,7 @@ export const apiFindAllByType = z
|
||||
"schedule",
|
||||
"previewDeployment",
|
||||
"backup",
|
||||
"volumeBackup",
|
||||
]),
|
||||
})
|
||||
.required();
|
||||
|
||||
@@ -12,6 +12,7 @@ import { compose } from "./compose";
|
||||
import { postgres } from "./postgres";
|
||||
import { mariadb } from "./mariadb";
|
||||
import { destinations } from "./destination";
|
||||
import { deployments } from "./deployment";
|
||||
|
||||
export const volumeBackups = pgTable("volume_backup", {
|
||||
volumeBackupId: text("volumeBackupId")
|
||||
@@ -61,36 +62,44 @@ export const volumeBackups = pgTable("volume_backup", {
|
||||
|
||||
export type VolumeBackup = typeof volumeBackups.$inferSelect;
|
||||
|
||||
export const volumeBackupsRelations = relations(volumeBackups, ({ one }) => ({
|
||||
application: one(applications, {
|
||||
fields: [volumeBackups.applicationId],
|
||||
references: [applications.applicationId],
|
||||
export const volumeBackupsRelations = relations(
|
||||
volumeBackups,
|
||||
({ one, many }) => ({
|
||||
application: one(applications, {
|
||||
fields: [volumeBackups.applicationId],
|
||||
references: [applications.applicationId],
|
||||
}),
|
||||
postgres: one(postgres, {
|
||||
fields: [volumeBackups.postgresId],
|
||||
references: [postgres.postgresId],
|
||||
}),
|
||||
mariadb: one(mariadb, {
|
||||
fields: [volumeBackups.mariadbId],
|
||||
references: [mariadb.mariadbId],
|
||||
}),
|
||||
mongo: one(mongo, {
|
||||
fields: [volumeBackups.mongoId],
|
||||
references: [mongo.mongoId],
|
||||
}),
|
||||
mysql: one(mysql, {
|
||||
fields: [volumeBackups.mysqlId],
|
||||
references: [mysql.mysqlId],
|
||||
}),
|
||||
redis: one(redis, {
|
||||
fields: [volumeBackups.redisId],
|
||||
references: [redis.redisId],
|
||||
}),
|
||||
compose: one(compose, {
|
||||
fields: [volumeBackups.composeId],
|
||||
references: [compose.composeId],
|
||||
}),
|
||||
destination: one(destinations, {
|
||||
fields: [volumeBackups.destinationId],
|
||||
references: [destinations.destinationId],
|
||||
}),
|
||||
deployments: many(deployments),
|
||||
}),
|
||||
postgres: one(postgres, {
|
||||
fields: [volumeBackups.postgresId],
|
||||
references: [postgres.postgresId],
|
||||
}),
|
||||
mariadb: one(mariadb, {
|
||||
fields: [volumeBackups.mariadbId],
|
||||
references: [mariadb.mariadbId],
|
||||
}),
|
||||
mongo: one(mongo, {
|
||||
fields: [volumeBackups.mongoId],
|
||||
references: [mongo.mongoId],
|
||||
}),
|
||||
mysql: one(mysql, {
|
||||
fields: [volumeBackups.mysqlId],
|
||||
references: [mysql.mysqlId],
|
||||
}),
|
||||
redis: one(redis, {
|
||||
fields: [volumeBackups.redisId],
|
||||
references: [redis.redisId],
|
||||
}),
|
||||
compose: one(compose, {
|
||||
fields: [volumeBackups.composeId],
|
||||
references: [compose.composeId],
|
||||
}),
|
||||
}));
|
||||
);
|
||||
|
||||
export const createVolumeBackupSchema = createInsertSchema(volumeBackups).omit({
|
||||
volumeBackupId: true,
|
||||
|
||||
Reference in New Issue
Block a user