diff --git a/packages/server/src/utils/backups/compose.ts b/packages/server/src/utils/backups/compose.ts index 8080bc50a..6640590b0 100644 --- a/packages/server/src/utils/backups/compose.ts +++ b/packages/server/src/utils/backups/compose.ts @@ -8,7 +8,12 @@ import { findEnvironmentById } from "@dokploy/server/services/environment"; import { findProjectById } from "@dokploy/server/services/project"; import { sendDatabaseBackupNotifications } from "../notifications/database-backup"; import { execAsync, execAsyncRemote } from "../process/execAsync"; -import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils"; +import { + getBackupCommand, + getBackupTimestamp, + getS3Credentials, + normalizeS3Path, +} from "./utils"; export const runComposeBackup = async ( compose: Compose, @@ -19,7 +24,7 @@ export const runComposeBackup = async ( const project = await findProjectById(environment.projectId); const { prefix, databaseType, serviceName } = backup; 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 bucketDestination = `${s3AppName}/${normalizeS3Path(prefix)}${backupFileName}`; const deployment = await createDeploymentBackup({ diff --git a/packages/server/src/utils/backups/libsql.ts b/packages/server/src/utils/backups/libsql.ts index e7880795c..a994db8bd 100644 --- a/packages/server/src/utils/backups/libsql.ts +++ b/packages/server/src/utils/backups/libsql.ts @@ -8,7 +8,12 @@ import type { Libsql } from "@dokploy/server/services/libsql"; import { findProjectById } from "@dokploy/server/services/project"; import { sendDatabaseBackupNotifications } from "../notifications/database-backup"; import { execAsync, execAsyncRemote } from "../process/execAsync"; -import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils"; +import { + getBackupCommand, + getBackupTimestamp, + getS3Credentials, + normalizeS3Path, +} from "./utils"; export const runLibsqlBackup = async ( libsql: Libsql, @@ -25,7 +30,7 @@ export const runLibsqlBackup = async ( }); const { prefix } = backup; const destination = backup.destination; - const backupFileName = `${new Date().toISOString()}.sql.gz`; + const backupFileName = `${getBackupTimestamp()}.sql.gz`; const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`; try { const rcloneFlags = getS3Credentials(destination); diff --git a/packages/server/src/utils/backups/mariadb.ts b/packages/server/src/utils/backups/mariadb.ts index 089b3cb04..dea22ff18 100644 --- a/packages/server/src/utils/backups/mariadb.ts +++ b/packages/server/src/utils/backups/mariadb.ts @@ -8,7 +8,12 @@ import type { Mariadb } from "@dokploy/server/services/mariadb"; import { findProjectById } from "@dokploy/server/services/project"; import { sendDatabaseBackupNotifications } from "../notifications/database-backup"; import { execAsync, execAsyncRemote } from "../process/execAsync"; -import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils"; +import { + getBackupCommand, + getBackupTimestamp, + getS3Credentials, + normalizeS3Path, +} from "./utils"; export const runMariadbBackup = async ( mariadb: Mariadb, @@ -19,7 +24,7 @@ export const runMariadbBackup = async ( const project = await findProjectById(environment.projectId); const { prefix } = backup; const destination = backup.destination; - const backupFileName = `${new Date().toISOString()}.sql.gz`; + const backupFileName = `${getBackupTimestamp()}.sql.gz`; const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`; const deployment = await createDeploymentBackup({ backupId: backup.backupId, diff --git a/packages/server/src/utils/backups/mongo.ts b/packages/server/src/utils/backups/mongo.ts index 34424f1ba..cebece14f 100644 --- a/packages/server/src/utils/backups/mongo.ts +++ b/packages/server/src/utils/backups/mongo.ts @@ -8,7 +8,12 @@ import type { Mongo } from "@dokploy/server/services/mongo"; import { findProjectById } from "@dokploy/server/services/project"; import { sendDatabaseBackupNotifications } from "../notifications/database-backup"; 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) => { const { environmentId, name, appName } = mongo; @@ -16,7 +21,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => { const project = await findProjectById(environment.projectId); const { prefix } = backup; const destination = backup.destination; - const backupFileName = `${new Date().toISOString()}.bson.gz`; + const backupFileName = `${getBackupTimestamp()}.bson.gz`; const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`; const deployment = await createDeploymentBackup({ backupId: backup.backupId, diff --git a/packages/server/src/utils/backups/mysql.ts b/packages/server/src/utils/backups/mysql.ts index 461a17bf9..a72f59880 100644 --- a/packages/server/src/utils/backups/mysql.ts +++ b/packages/server/src/utils/backups/mysql.ts @@ -8,7 +8,12 @@ import type { MySql } from "@dokploy/server/services/mysql"; import { findProjectById } from "@dokploy/server/services/project"; import { sendDatabaseBackupNotifications } from "../notifications/database-backup"; 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) => { const { environmentId, name, appName } = mysql; @@ -16,7 +21,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => { const project = await findProjectById(environment.projectId); const { prefix } = backup; const destination = backup.destination; - const backupFileName = `${new Date().toISOString()}.sql.gz`; + const backupFileName = `${getBackupTimestamp()}.sql.gz`; const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`; const deployment = await createDeploymentBackup({ backupId: backup.backupId, diff --git a/packages/server/src/utils/backups/postgres.ts b/packages/server/src/utils/backups/postgres.ts index 3371b0cf9..30a88db2b 100644 --- a/packages/server/src/utils/backups/postgres.ts +++ b/packages/server/src/utils/backups/postgres.ts @@ -8,7 +8,12 @@ import type { Postgres } from "@dokploy/server/services/postgres"; import { findProjectById } from "@dokploy/server/services/project"; import { sendDatabaseBackupNotifications } from "../notifications/database-backup"; import { execAsync, execAsyncRemote } from "../process/execAsync"; -import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils"; +import { + getBackupCommand, + getBackupTimestamp, + getS3Credentials, + normalizeS3Path, +} from "./utils"; export const runPostgresBackup = async ( postgres: Postgres, @@ -25,7 +30,7 @@ export const runPostgresBackup = async ( }); const { prefix } = backup; const destination = backup.destination; - const backupFileName = `${new Date().toISOString()}.sql.gz`; + const backupFileName = `${getBackupTimestamp()}.sql.gz`; const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`; try { const rcloneFlags = getS3Credentials(destination); diff --git a/packages/server/src/utils/backups/utils.ts b/packages/server/src/utils/backups/utils.ts index 9d6a5373d..365ebff41 100644 --- a/packages/server/src/utils/backups/utils.ts +++ b/packages/server/src/utils/backups/utils.ts @@ -56,6 +56,9 @@ export const removeScheduleBackup = (backupId: string) => { currentJob?.cancel(); }; +export const getBackupTimestamp = () => + new Date().toISOString().replace(/[:.]/g, "-"); + export const normalizeS3Path = (prefix: string) => { // Trim whitespace and remove leading/trailing slashes const normalizedPrefix = prefix.trim().replace(/^\/+|\/+$/g, ""); diff --git a/packages/server/src/utils/backups/web-server.ts b/packages/server/src/utils/backups/web-server.ts index 19dd44eed..19975cd6f 100644 --- a/packages/server/src/utils/backups/web-server.ts +++ b/packages/server/src/utils/backups/web-server.ts @@ -11,7 +11,7 @@ import { import { findDestinationById } from "@dokploy/server/services/destination"; import { sendDokployBackupNotifications } from "../notifications/dokploy-backup"; import { execAsync } from "../process/execAsync"; -import { getS3Credentials, normalizeS3Path } from "./utils"; +import { getBackupTimestamp, getS3Credentials, normalizeS3Path } from "./utils"; function formatBytes(bytes?: number) { if (bytes === undefined) return "Unknown size"; @@ -37,7 +37,7 @@ export const runWebServerBackup = async (backup: BackupSchedule) => { try { const destination = await findDestinationById(backup.destinationId); const rcloneFlags = getS3Credentials(destination); - const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const timestamp = getBackupTimestamp(); const { BASE_PATH } = paths(); const tempDir = await mkdtemp(join(tmpdir(), "dokploy-backup-")); const backupFileName = `webserver-backup-${timestamp}.zip`; diff --git a/packages/server/src/utils/volume-backups/backup.ts b/packages/server/src/utils/volume-backups/backup.ts index d2827a3f0..1d795a14a 100644 --- a/packages/server/src/utils/volume-backups/backup.ts +++ b/packages/server/src/utils/volume-backups/backup.ts @@ -2,7 +2,11 @@ import path from "node:path"; import { paths } from "@dokploy/server/constants"; import { findComposeById } from "@dokploy/server/services/compose"; 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 = ( volumeBackup: Awaited>, @@ -32,7 +36,7 @@ export const backupVolume = async ( const { VOLUME_BACKUPS_PATH, VOLUME_BACKUP_LOCK_PATH } = paths(!!serverId); const destination = volumeBackup.destination; const s3AppName = getVolumeServiceAppName(volumeBackup); - const backupFileName = `${volumeName}-${new Date().toISOString()}.tar`; + const backupFileName = `${volumeName}-${getBackupTimestamp()}.tar`; const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix || "")}${backupFileName}`; const rcloneFlags = getS3Credentials(volumeBackup.destination); const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;