mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
Enhance backup validation and improve backup display
- Added validation to require a service name for compose backups in the backup handling logic, improving user feedback. - Refactored the ShowBackups component to sort deployments by creation date and enhance the display of backup information, including service names and statuses, for better user experience. - Updated logging in the compose backup utility to include command execution details, aiding in debugging and monitoring.
This commit is contained in:
@@ -108,6 +108,15 @@ const Schema = z
|
|||||||
path: ["databaseType"],
|
path: ["databaseType"],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.backupType === "compose" && !data.serviceName) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: "Service name is required for compose backups",
|
||||||
|
path: ["serviceName"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (data.backupType === "compose" && data.databaseType) {
|
if (data.backupType === "compose" && data.databaseType) {
|
||||||
if (data.databaseType === "postgres") {
|
if (data.databaseType === "postgres") {
|
||||||
if (!data.metadata?.postgres?.databaseUser) {
|
if (!data.metadata?.postgres?.databaseUser) {
|
||||||
|
|||||||
@@ -178,7 +178,17 @@ export const ShowBackups = ({
|
|||||||
</AlertBlock>
|
</AlertBlock>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
{postgres?.backups.map((backup) => (
|
{postgres?.backups.map((backup) => {
|
||||||
|
const orderedDeployments = backup.deployments.sort(
|
||||||
|
(a, b) =>
|
||||||
|
new Date(b.createdAt).getTime() -
|
||||||
|
new Date(a.createdAt).getTime(),
|
||||||
|
);
|
||||||
|
|
||||||
|
const serverId =
|
||||||
|
"serverId" in postgres ? postgres.serverId : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
<div key={backup.backupId}>
|
<div key={backup.backupId}>
|
||||||
<div className="flex w-full flex-col md:flex-row md:items-start justify-between gap-4 border rounded-lg p-4 hover:bg-muted/50 transition-colors">
|
<div className="flex w-full flex-col md:flex-row md:items-start justify-between gap-4 border rounded-lg p-4 hover:bg-muted/50 transition-colors">
|
||||||
<div className="flex flex-col w-full gap-4">
|
<div className="flex flex-col w-full gap-4">
|
||||||
@@ -275,7 +285,10 @@ export const ShowBackups = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row md:flex-col gap-1.5">
|
<div className="flex flex-row md:flex-col gap-1.5">
|
||||||
<ShowSchedulesLogs deployments={backup.deployments}>
|
<ShowSchedulesLogs
|
||||||
|
deployments={orderedDeployments}
|
||||||
|
serverId={serverId || undefined}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
@@ -317,7 +330,9 @@ export const ShowBackups = ({
|
|||||||
<Play className="size-4 " />
|
<Play className="size-4 " />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>Run Manual Backup</TooltipContent>
|
<TooltipContent>
|
||||||
|
Run Manual Backup
|
||||||
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|
||||||
@@ -336,7 +351,9 @@ export const ShowBackups = ({
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
refetch();
|
refetch();
|
||||||
toast.success("Backup deleted successfully");
|
toast.success(
|
||||||
|
"Backup deleted successfully",
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error("Error deleting backup");
|
toast.error("Error deleting backup");
|
||||||
@@ -355,7 +372,8 @@ export const ShowBackups = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export const runComposeBackup = async (
|
|||||||
title: "Compose Backup",
|
title: "Compose Backup",
|
||||||
description: "Compose Backup",
|
description: "Compose Backup",
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = getS3Credentials(destination);
|
const rcloneFlags = getS3Credentials(destination);
|
||||||
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
||||||
@@ -77,7 +78,8 @@ export const runComposeBackup = async (
|
|||||||
compose.serverId,
|
compose.serverId,
|
||||||
`
|
`
|
||||||
set -e;
|
set -e;
|
||||||
Running command.
|
echo "Running command." >> ${deployment.logPath};
|
||||||
|
export RCLONE_LOG_LEVEL=DEBUG;
|
||||||
${backupCommand} | ${rcloneCommand} >> ${deployment.logPath} 2>> ${deployment.logPath} || {
|
${backupCommand} | ${rcloneCommand} >> ${deployment.logPath} 2>> ${deployment.logPath} || {
|
||||||
echo "❌ Command failed" >> ${deployment.logPath};
|
echo "❌ Command failed" >> ${deployment.logPath};
|
||||||
exit 1;
|
exit 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user