mirror of
https://github.com/andwati/dokploy.git
synced 2026-10-18 11:12:56 +00:00
- Added `apiRestoreBackup` schema to define input requirements for restore operations. - Refactored restore utilities for PostgreSQL, MySQL, MariaDB, and MongoDB to utilize a unified command generation approach, enhancing maintainability. - Improved logging during restore processes to provide clearer feedback on command execution and success/failure states. - Streamlined the handling of database credentials and backup file paths across different database types, ensuring consistency and reducing redundancy.
98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
import type { Destination } from "@dokploy/server/services/destination";
|
|
import type { Compose } from "@dokploy/server/services/compose";
|
|
import { getS3Credentials } from "../backups/utils";
|
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
|
import { getRestoreCommand } from "./utils";
|
|
import type { apiRestoreBackup } from "@dokploy/server/db/schema";
|
|
import type { z } from "zod";
|
|
|
|
interface DatabaseCredentials {
|
|
databaseUser?: string;
|
|
databasePassword?: string;
|
|
}
|
|
|
|
export const restoreComposeBackup = async (
|
|
compose: Compose,
|
|
destination: Destination,
|
|
backupInput: z.infer<typeof apiRestoreBackup>,
|
|
emit: (log: string) => void,
|
|
) => {
|
|
try {
|
|
if (backupInput.databaseType === "web-server") {
|
|
return;
|
|
}
|
|
const { serverId, appName, composeType } = compose;
|
|
|
|
const rcloneFlags = getS3Credentials(destination);
|
|
const bucketPath = `:s3:${destination.bucket}`;
|
|
const backupPath = `${bucketPath}/${backupInput.backupFile}`;
|
|
let rcloneCommand = `rclone cat ${rcloneFlags.join(" ")} "${backupPath}" | gunzip`;
|
|
|
|
if (backupInput.metadata?.mongo) {
|
|
rcloneCommand = `rclone copy ${rcloneFlags.join(" ")} "${backupPath}"`;
|
|
}
|
|
|
|
let credentials: DatabaseCredentials;
|
|
|
|
switch (backupInput.databaseType) {
|
|
case "postgres":
|
|
credentials = {
|
|
databaseUser: backupInput.metadata?.postgres?.databaseUser,
|
|
};
|
|
break;
|
|
case "mariadb":
|
|
credentials = {
|
|
databaseUser: backupInput.metadata?.mariadb?.databaseUser,
|
|
databasePassword: backupInput.metadata?.mariadb?.databasePassword,
|
|
};
|
|
break;
|
|
case "mysql":
|
|
credentials = {
|
|
databasePassword: backupInput.metadata?.mysql?.databaseRootPassword,
|
|
};
|
|
break;
|
|
case "mongo":
|
|
credentials = {
|
|
databaseUser: backupInput.metadata?.mongo?.databaseUser,
|
|
databasePassword: backupInput.metadata?.mongo?.databasePassword,
|
|
};
|
|
break;
|
|
}
|
|
|
|
const restoreCommand = getRestoreCommand({
|
|
appName: appName,
|
|
serviceName: backupInput.metadata?.serviceName,
|
|
type: backupInput.databaseType,
|
|
credentials: {
|
|
database: backupInput.databaseName,
|
|
...credentials,
|
|
},
|
|
restoreType: composeType,
|
|
rcloneCommand,
|
|
});
|
|
|
|
emit("Starting restore...");
|
|
emit(`Backup path: ${backupPath}`);
|
|
|
|
emit(`Executing command: ${restoreCommand}`);
|
|
|
|
if (serverId) {
|
|
await execAsyncRemote(serverId, restoreCommand);
|
|
} else {
|
|
await execAsync(restoreCommand);
|
|
}
|
|
|
|
emit("Restore completed successfully!");
|
|
} catch (error) {
|
|
console.error(error);
|
|
emit(
|
|
`Error: ${
|
|
error instanceof Error ? error.message : "Error restoring mongo backup"
|
|
}`,
|
|
);
|
|
throw new Error(
|
|
error instanceof Error ? error.message : "Error restoring mongo backup",
|
|
);
|
|
}
|
|
};
|