mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-13 07:25:17 +00:00
Merge pull request #2956 from Harikrishnan1367709/Change-backup-file-naming-structure-#2955
Feat : Fix backup file naming for Windows 11 compatibility (#2955)
This commit is contained in:
@@ -8,7 +8,12 @@ import { findEnvironmentById } from "@dokploy/server/services/environment";
|
|||||||
import { findProjectById } from "@dokploy/server/services/project";
|
import { findProjectById } from "@dokploy/server/services/project";
|
||||||
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
|
import {
|
||||||
|
getBackupCommand,
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
export const runComposeBackup = async (
|
export const runComposeBackup = async (
|
||||||
compose: Compose,
|
compose: Compose,
|
||||||
@@ -19,7 +24,7 @@ export const runComposeBackup = async (
|
|||||||
const project = await findProjectById(environment.projectId);
|
const project = await findProjectById(environment.projectId);
|
||||||
const { prefix, databaseType, serviceName } = backup;
|
const { prefix, databaseType, serviceName } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.${databaseType === "mongo" ? "bson" : "sql"}.gz`;
|
const backupFileName = `${getBackupTimestamp()}.${databaseType === "mongo" ? "bson" : "sql"}.gz`;
|
||||||
const s3AppName = serviceName ? `${appName}_${serviceName}` : appName;
|
const s3AppName = serviceName ? `${appName}_${serviceName}` : appName;
|
||||||
const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import type { Libsql } from "@dokploy/server/services/libsql";
|
|||||||
import { findProjectById } from "@dokploy/server/services/project";
|
import { findProjectById } from "@dokploy/server/services/project";
|
||||||
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
|
import {
|
||||||
|
getBackupCommand,
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
export const runLibsqlBackup = async (
|
export const runLibsqlBackup = async (
|
||||||
libsql: Libsql,
|
libsql: Libsql,
|
||||||
@@ -25,7 +30,7 @@ export const runLibsqlBackup = async (
|
|||||||
});
|
});
|
||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${getBackupTimestamp()}.sql.gz`;
|
||||||
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = getS3Credentials(destination);
|
const rcloneFlags = getS3Credentials(destination);
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import type { Mariadb } from "@dokploy/server/services/mariadb";
|
|||||||
import { findProjectById } from "@dokploy/server/services/project";
|
import { findProjectById } from "@dokploy/server/services/project";
|
||||||
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
|
import {
|
||||||
|
getBackupCommand,
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
export const runMariadbBackup = async (
|
export const runMariadbBackup = async (
|
||||||
mariadb: Mariadb,
|
mariadb: Mariadb,
|
||||||
@@ -19,7 +24,7 @@ export const runMariadbBackup = async (
|
|||||||
const project = await findProjectById(environment.projectId);
|
const project = await findProjectById(environment.projectId);
|
||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${getBackupTimestamp()}.sql.gz`;
|
||||||
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import type { Mongo } from "@dokploy/server/services/mongo";
|
|||||||
import { findProjectById } from "@dokploy/server/services/project";
|
import { findProjectById } from "@dokploy/server/services/project";
|
||||||
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
|
import {
|
||||||
|
getBackupCommand,
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
||||||
const { environmentId, name, appName } = mongo;
|
const { environmentId, name, appName } = mongo;
|
||||||
@@ -16,7 +21,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
|||||||
const project = await findProjectById(environment.projectId);
|
const project = await findProjectById(environment.projectId);
|
||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.bson.gz`;
|
const backupFileName = `${getBackupTimestamp()}.bson.gz`;
|
||||||
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import type { MySql } from "@dokploy/server/services/mysql";
|
|||||||
import { findProjectById } from "@dokploy/server/services/project";
|
import { findProjectById } from "@dokploy/server/services/project";
|
||||||
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
|
import {
|
||||||
|
getBackupCommand,
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
||||||
const { environmentId, name, appName } = mysql;
|
const { environmentId, name, appName } = mysql;
|
||||||
@@ -16,7 +21,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
|||||||
const project = await findProjectById(environment.projectId);
|
const project = await findProjectById(environment.projectId);
|
||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${getBackupTimestamp()}.sql.gz`;
|
||||||
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ import type { Postgres } from "@dokploy/server/services/postgres";
|
|||||||
import { findProjectById } from "@dokploy/server/services/project";
|
import { findProjectById } from "@dokploy/server/services/project";
|
||||||
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
import { sendDatabaseBackupNotifications } from "../notifications/database-backup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
|
import {
|
||||||
|
getBackupCommand,
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "./utils";
|
||||||
|
|
||||||
export const runPostgresBackup = async (
|
export const runPostgresBackup = async (
|
||||||
postgres: Postgres,
|
postgres: Postgres,
|
||||||
@@ -25,7 +30,7 @@ export const runPostgresBackup = async (
|
|||||||
});
|
});
|
||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${getBackupTimestamp()}.sql.gz`;
|
||||||
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = getS3Credentials(destination);
|
const rcloneFlags = getS3Credentials(destination);
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ export const removeScheduleBackup = (backupId: string) => {
|
|||||||
currentJob?.cancel();
|
currentJob?.cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getBackupTimestamp = () =>
|
||||||
|
new Date().toISOString().replace(/[:.]/g, "-");
|
||||||
|
|
||||||
export const normalizeS3Path = (prefix: string) => {
|
export const normalizeS3Path = (prefix: string) => {
|
||||||
// Trim whitespace and remove leading/trailing slashes
|
// Trim whitespace and remove leading/trailing slashes
|
||||||
const normalizedPrefix = prefix.trim().replace(/^\/+|\/+$/g, "");
|
const normalizedPrefix = prefix.trim().replace(/^\/+|\/+$/g, "");
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
import { findDestinationById } from "@dokploy/server/services/destination";
|
import { findDestinationById } from "@dokploy/server/services/destination";
|
||||||
import { sendDokployBackupNotifications } from "../notifications/dokploy-backup";
|
import { sendDokployBackupNotifications } from "../notifications/dokploy-backup";
|
||||||
import { execAsync } from "../process/execAsync";
|
import { execAsync } from "../process/execAsync";
|
||||||
import { getS3Credentials, normalizeS3Path } from "./utils";
|
import { getBackupTimestamp, getS3Credentials, normalizeS3Path } from "./utils";
|
||||||
|
|
||||||
function formatBytes(bytes?: number) {
|
function formatBytes(bytes?: number) {
|
||||||
if (bytes === undefined) return "Unknown size";
|
if (bytes === undefined) return "Unknown size";
|
||||||
@@ -37,7 +37,7 @@ export const runWebServerBackup = async (backup: BackupSchedule) => {
|
|||||||
try {
|
try {
|
||||||
const destination = await findDestinationById(backup.destinationId);
|
const destination = await findDestinationById(backup.destinationId);
|
||||||
const rcloneFlags = getS3Credentials(destination);
|
const rcloneFlags = getS3Credentials(destination);
|
||||||
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
const timestamp = getBackupTimestamp();
|
||||||
const { BASE_PATH } = paths();
|
const { BASE_PATH } = paths();
|
||||||
const tempDir = await mkdtemp(join(tmpdir(), "dokploy-backup-"));
|
const tempDir = await mkdtemp(join(tmpdir(), "dokploy-backup-"));
|
||||||
const backupFileName = `webserver-backup-${timestamp}.zip`;
|
const backupFileName = `webserver-backup-${timestamp}.zip`;
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import path from "node:path";
|
|||||||
import { paths } from "@dokploy/server/constants";
|
import { paths } from "@dokploy/server/constants";
|
||||||
import { findComposeById } from "@dokploy/server/services/compose";
|
import { findComposeById } from "@dokploy/server/services/compose";
|
||||||
import type { findVolumeBackupById } from "@dokploy/server/services/volume-backups";
|
import type { findVolumeBackupById } from "@dokploy/server/services/volume-backups";
|
||||||
import { getS3Credentials, normalizeS3Path } from "../backups/utils";
|
import {
|
||||||
|
getBackupTimestamp,
|
||||||
|
getS3Credentials,
|
||||||
|
normalizeS3Path,
|
||||||
|
} from "../backups/utils";
|
||||||
|
|
||||||
export const getVolumeServiceAppName = (
|
export const getVolumeServiceAppName = (
|
||||||
volumeBackup: Awaited<ReturnType<typeof findVolumeBackupById>>,
|
volumeBackup: Awaited<ReturnType<typeof findVolumeBackupById>>,
|
||||||
@@ -32,7 +36,7 @@ export const backupVolume = async (
|
|||||||
const { VOLUME_BACKUPS_PATH, VOLUME_BACKUP_LOCK_PATH } = paths(!!serverId);
|
const { VOLUME_BACKUPS_PATH, VOLUME_BACKUP_LOCK_PATH } = paths(!!serverId);
|
||||||
const destination = volumeBackup.destination;
|
const destination = volumeBackup.destination;
|
||||||
const s3AppName = getVolumeServiceAppName(volumeBackup);
|
const s3AppName = getVolumeServiceAppName(volumeBackup);
|
||||||
const backupFileName = `${volumeName}-${new Date().toISOString()}.tar`;
|
const backupFileName = `${volumeName}-${getBackupTimestamp()}.tar`;
|
||||||
const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix || "")}${backupFileName}`;
|
const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix || "")}${backupFileName}`;
|
||||||
const rcloneFlags = getS3Credentials(volumeBackup.destination);
|
const rcloneFlags = getS3Credentials(volumeBackup.destination);
|
||||||
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user