Skip to content

Commit e9787b7

Browse files
authored
Merge pull request #3934 from Dokploy/feat/use-appname-on-backups-folder
Feat/use appname on backups folder
2 parents dc8ff78 + b419294 commit e9787b7

9 files changed

Lines changed: 52 additions & 16 deletions

File tree

packages/server/src/utils/backups/compose.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ export const runComposeBackup = async (
1414
compose: Compose,
1515
backup: BackupSchedule,
1616
) => {
17-
const { environmentId, name } = compose;
17+
const { environmentId, name, appName } = compose;
1818
const environment = await findEnvironmentById(environmentId);
1919
const project = await findProjectById(environment.projectId);
20-
const { prefix, databaseType } = backup;
20+
const { prefix, databaseType, serviceName } = backup;
2121
const destination = backup.destination;
2222
const backupFileName = `${new Date().toISOString()}.sql.gz`;
23-
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
23+
const s3AppName = serviceName ? `${appName}_${serviceName}` : appName;
24+
const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix)}${backupFileName}`;
2425
const deployment = await createDeploymentBackup({
2526
backupId: backup.backupId,
2627
title: "Compose Backup",

packages/server/src/utils/backups/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,20 @@ export const initCronJobs = async () => {
106106
}
107107
};
108108

109+
const getServiceAppName = (backup: BackupSchedule): string => {
110+
if (backup.compose?.appName) {
111+
return backup.serviceName
112+
? `${backup.compose.appName}_${backup.serviceName}`
113+
: backup.compose.appName;
114+
}
115+
const serviceAppName =
116+
backup.postgres?.appName ||
117+
backup.mysql?.appName ||
118+
backup.mariadb?.appName ||
119+
backup.mongo?.appName;
120+
return serviceAppName || backup.appName;
121+
};
122+
109123
export const keepLatestNBackups = async (
110124
backup: BackupSchedule,
111125
serverId?: string | null,
@@ -116,7 +130,8 @@ export const keepLatestNBackups = async (
116130

117131
try {
118132
const rcloneFlags = getS3Credentials(backup.destination);
119-
const backupFilesPath = `:s3:${backup.destination.bucket}/${backup.appName}/${normalizeS3Path(backup.prefix)}`;
133+
const appName = getServiceAppName(backup);
134+
const backupFilesPath = `:s3:${backup.destination.bucket}/${appName}/${normalizeS3Path(backup.prefix)}`;
120135

121136
// --include "*.sql.gz" or "*.zip" ensures nothing else other than the dokploy backup files are touched by rclone
122137
const rcloneList = `rclone lsf ${rcloneFlags.join(" ")} --include "*${backup.databaseType === "web-server" ? ".zip" : ".sql.gz"}" ${backupFilesPath}`;

packages/server/src/utils/backups/mariadb.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ export const runMariadbBackup = async (
1414
mariadb: Mariadb,
1515
backup: BackupSchedule,
1616
) => {
17-
const { environmentId, name } = mariadb;
17+
const { environmentId, name, appName } = mariadb;
1818
const environment = await findEnvironmentById(environmentId);
1919
const project = await findProjectById(environment.projectId);
2020
const { prefix } = backup;
2121
const destination = backup.destination;
2222
const backupFileName = `${new Date().toISOString()}.sql.gz`;
23-
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
23+
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
2424
const deployment = await createDeploymentBackup({
2525
backupId: backup.backupId,
2626
title: "MariaDB Backup",

packages/server/src/utils/backups/mongo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import { execAsync, execAsyncRemote } from "../process/execAsync";
1111
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
1212

1313
export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
14-
const { environmentId, name } = mongo;
14+
const { environmentId, name, appName } = mongo;
1515
const environment = await findEnvironmentById(environmentId);
1616
const project = await findProjectById(environment.projectId);
1717
const { prefix } = backup;
1818
const destination = backup.destination;
1919
const backupFileName = `${new Date().toISOString()}.sql.gz`;
20-
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
20+
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
2121
const deployment = await createDeploymentBackup({
2222
backupId: backup.backupId,
2323
title: "MongoDB Backup",

packages/server/src/utils/backups/mysql.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import { execAsync, execAsyncRemote } from "../process/execAsync";
1111
import { getBackupCommand, getS3Credentials, normalizeS3Path } from "./utils";
1212

1313
export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
14-
const { environmentId, name } = mysql;
14+
const { environmentId, name, appName } = mysql;
1515
const environment = await findEnvironmentById(environmentId);
1616
const project = await findProjectById(environment.projectId);
1717
const { prefix } = backup;
1818
const destination = backup.destination;
1919
const backupFileName = `${new Date().toISOString()}.sql.gz`;
20-
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
20+
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
2121
const deployment = await createDeploymentBackup({
2222
backupId: backup.backupId,
2323
title: "MySQL Backup",

packages/server/src/utils/backups/postgres.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const runPostgresBackup = async (
1414
postgres: Postgres,
1515
backup: BackupSchedule,
1616
) => {
17-
const { name, environmentId } = postgres;
17+
const { name, environmentId, appName } = postgres;
1818
const environment = await findEnvironmentById(environmentId);
1919
const project = await findProjectById(environment.projectId);
2020

@@ -26,7 +26,7 @@ export const runPostgresBackup = async (
2626
const { prefix } = backup;
2727
const destination = backup.destination;
2828
const backupFileName = `${new Date().toISOString()}.sql.gz`;
29-
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
29+
const bucketDestination = `${appName}/${normalizeS3Path(prefix)}${backupFileName}`;
3030
try {
3131
const rcloneFlags = getS3Credentials(destination);
3232
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;

packages/server/src/utils/restore/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const getMongoRestoreCommand = (
3030
databaseUser: string,
3131
databasePassword: string,
3232
) => {
33-
return `docker exec -i $CONTAINER_ID sh -c "mongorestore --username '${databaseUser}' --password '${databasePassword}' --authenticationDatabase admin --db ${database} --archive"`;
33+
return `docker exec -i $CONTAINER_ID sh -c "mongorestore --username '${databaseUser}' --password '${databasePassword}' --authenticationDatabase admin --db ${database} --archive --drop"`;
3434
};
3535

3636
export const getComposeSearchCommand = (

packages/server/src/utils/volume-backups/backup.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@ import { findComposeById } from "@dokploy/server/services/compose";
44
import type { findVolumeBackupById } from "@dokploy/server/services/volume-backups";
55
import { getS3Credentials, normalizeS3Path } from "../backups/utils";
66

7+
export const getVolumeServiceAppName = (
8+
volumeBackup: Awaited<ReturnType<typeof findVolumeBackupById>>,
9+
): string => {
10+
if (volumeBackup.compose?.appName) {
11+
return volumeBackup.serviceName
12+
? `${volumeBackup.compose.appName}_${volumeBackup.serviceName}`
13+
: volumeBackup.compose.appName;
14+
}
15+
const serviceAppName =
16+
volumeBackup.application?.appName ||
17+
volumeBackup.postgres?.appName ||
18+
volumeBackup.mysql?.appName ||
19+
volumeBackup.mariadb?.appName ||
20+
volumeBackup.mongo?.appName ||
21+
volumeBackup.redis?.appName;
22+
return serviceAppName || volumeBackup.appName;
23+
};
24+
725
export const backupVolume = async (
826
volumeBackup: Awaited<ReturnType<typeof findVolumeBackupById>>,
927
) => {
@@ -12,8 +30,9 @@ export const backupVolume = async (
1230
volumeBackup.application?.serverId || volumeBackup.compose?.serverId;
1331
const { VOLUME_BACKUPS_PATH, VOLUME_BACKUP_LOCK_PATH } = paths(!!serverId);
1432
const destination = volumeBackup.destination;
33+
const s3AppName = getVolumeServiceAppName(volumeBackup);
1534
const backupFileName = `${volumeName}-${new Date().toISOString()}.tar`;
16-
const bucketDestination = `${volumeBackup.appName}/${normalizeS3Path(prefix || "")}${backupFileName}`;
35+
const bucketDestination = `${s3AppName}/${normalizeS3Path(prefix || "")}${backupFileName}`;
1736
const rcloneFlags = getS3Credentials(volumeBackup.destination);
1837
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
1938
const volumeBackupPath = path.join(VOLUME_BACKUPS_PATH, volumeBackup.appName);

packages/server/src/utils/volume-backups/utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { scheduledJobs, scheduleJob } from "node-schedule";
1313
import { getS3Credentials, normalizeS3Path } from "../backups/utils";
1414
import { sendVolumeBackupNotifications } from "../notifications/volume-backup";
15-
import { backupVolume } from "./backup";
15+
import { backupVolume, getVolumeServiceAppName } from "./backup";
1616

1717
// Helper functions to extract project info from volume backup
1818
const getProjectName = (
@@ -81,7 +81,8 @@ const cleanupOldVolumeBackups = async (
8181

8282
try {
8383
const rcloneFlags = getS3Credentials(destination);
84-
const backupFilesPath = `:s3:${destination.bucket}/${volumeBackup.appName}/${normalizeS3Path(prefix || "")}`;
84+
const s3AppName = getVolumeServiceAppName(volumeBackup);
85+
const backupFilesPath = `:s3:${destination.bucket}/${s3AppName}/${normalizeS3Path(prefix || "")}`;
8586
const listCommand = `rclone lsf ${rcloneFlags.join(" ")} --include \"${volumeName}-*.tar\" ${backupFilesPath}`;
8687
const sortAndPick = `sort -r | tail -n +$((${keepLatestCount}+1)) | xargs -I{}`;
8788
const deleteCommand = `rclone delete ${rcloneFlags.join(" ")} ${backupFilesPath}{}`;

0 commit comments

Comments
 (0)