mirror of
https://github.com/andwati/dokploy.git
synced 2026-10-29 08:12:15 +00:00
refactor: update backup file paths to include app name for better organization
This commit is contained in:
@@ -20,7 +20,7 @@ export const runComposeBackup = async (
|
|||||||
const { prefix, databaseType } = backup;
|
const { prefix, databaseType } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
||||||
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
title: "Compose Backup",
|
title: "Compose Backup",
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import path from "node:path";
|
|
||||||
import { CLEANUP_CRON_JOB } from "@dokploy/server/constants";
|
import { CLEANUP_CRON_JOB } from "@dokploy/server/constants";
|
||||||
import { member } from "@dokploy/server/db/schema";
|
import { member } from "@dokploy/server/db/schema";
|
||||||
import type { BackupSchedule } from "@dokploy/server/services/backup";
|
import type { BackupSchedule } from "@dokploy/server/services/backup";
|
||||||
@@ -11,7 +10,7 @@ import { startLogCleanup } from "../access-log/handler";
|
|||||||
import { cleanupAll } from "../docker/utils";
|
import { cleanupAll } from "../docker/utils";
|
||||||
import { sendDockerCleanupNotifications } from "../notifications/docker-cleanup";
|
import { sendDockerCleanupNotifications } from "../notifications/docker-cleanup";
|
||||||
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
import { execAsync, execAsyncRemote } from "../process/execAsync";
|
||||||
import { getS3Credentials, scheduleBackup } from "./utils";
|
import { getS3Credentials, normalizeS3Path, scheduleBackup } from "./utils";
|
||||||
|
|
||||||
export const initCronJobs = async () => {
|
export const initCronJobs = async () => {
|
||||||
console.log("Setting up cron jobs....");
|
console.log("Setting up cron jobs....");
|
||||||
@@ -117,18 +116,15 @@ export const keepLatestNBackups = async (
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = getS3Credentials(backup.destination);
|
const rcloneFlags = getS3Credentials(backup.destination);
|
||||||
const backupFilesPath = path.join(
|
const backupFilesPath = `:s3:${backup.destination.bucket}/${backup.appName}/${normalizeS3Path(backup.prefix)}`;
|
||||||
`:s3:${backup.destination.bucket}`,
|
|
||||||
backup.prefix,
|
|
||||||
);
|
|
||||||
|
|
||||||
// --include "*.sql.gz" or "*.zip" ensures nothing else other than the dokploy backup files are touched by rclone
|
// --include "*.sql.gz" or "*.zip" ensures nothing else other than the dokploy backup files are touched by rclone
|
||||||
const rcloneList = `rclone lsf ${rcloneFlags.join(" ")} --include "*${backup.databaseType === "web-server" ? ".zip" : ".sql.gz"}" ${backupFilesPath}`;
|
const rcloneList = `rclone lsf ${rcloneFlags.join(" ")} --include "*${backup.databaseType === "web-server" ? ".zip" : ".sql.gz"}" ${backupFilesPath}`;
|
||||||
// when we pipe the above command with this one, we only get the list of files we want to delete
|
// when we pipe the above command with this one, we only get the list of files we want to delete
|
||||||
const sortAndPickUnwantedBackups = `sort -r | tail -n +$((${backup.keepLatestCount}+1)) | xargs -I{}`;
|
const sortAndPickUnwantedBackups = `sort -r | tail -n +$((${backup.keepLatestCount}+1)) | xargs -I{}`;
|
||||||
// this command deletes the files
|
// this command deletes the files
|
||||||
// to test the deletion before actually deleting we can add --dry-run before ${backupFilesPath}/{}
|
// to test the deletion before actually deleting we can add --dry-run before ${backupFilesPath}{}
|
||||||
const rcloneDelete = `rclone delete ${rcloneFlags.join(" ")} ${backupFilesPath}/{}`;
|
const rcloneDelete = `rclone delete ${rcloneFlags.join(" ")} ${backupFilesPath}{}`;
|
||||||
|
|
||||||
const rcloneCommand = `${rcloneList} | ${sortAndPickUnwantedBackups} ${rcloneDelete}`;
|
const rcloneCommand = `${rcloneList} | ${sortAndPickUnwantedBackups} ${rcloneDelete}`;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const runMariadbBackup = async (
|
|||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
||||||
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
title: "MariaDB Backup",
|
title: "MariaDB Backup",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
|
|||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
||||||
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
title: "MongoDB Backup",
|
title: "MongoDB Backup",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
|
|||||||
const { prefix } = backup;
|
const { prefix } = backup;
|
||||||
const destination = backup.destination;
|
const destination = backup.destination;
|
||||||
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
const backupFileName = `${new Date().toISOString()}.sql.gz`;
|
||||||
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
const deployment = await createDeploymentBackup({
|
const deployment = await createDeploymentBackup({
|
||||||
backupId: backup.backupId,
|
backupId: backup.backupId,
|
||||||
title: "MySQL Backup",
|
title: "MySQL Backup",
|
||||||
|
|||||||
@@ -26,7 +26,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 = `${new Date().toISOString()}.sql.gz`;
|
||||||
const bucketDestination = `${normalizeS3Path(prefix)}${backupFileName}`;
|
const bucketDestination = `${backup.appName}/${normalizeS3Path(prefix)}${backupFileName}`;
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = getS3Credentials(destination);
|
const rcloneFlags = getS3Credentials(destination);
|
||||||
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const runWebServerBackup = async (backup: BackupSchedule) => {
|
|||||||
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`;
|
||||||
const s3Path = `:s3:${destination.bucket}/${normalizeS3Path(backup.prefix)}${backupFileName}`;
|
const s3Path = `:s3:${destination.bucket}/${backup.appName}/${normalizeS3Path(backup.prefix)}${backupFileName}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await execAsync(`mkdir -p ${tempDir}/filesystem`);
|
await execAsync(`mkdir -p ${tempDir}/filesystem`);
|
||||||
|
|||||||
@@ -13,10 +13,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 backupFileName = `${volumeName}-${new Date().toISOString()}.tar`;
|
const backupFileName = `${volumeName}-${new Date().toISOString()}.tar`;
|
||||||
const effectivePrefix = prefix
|
const bucketDestination = `${volumeBackup.appName}/${normalizeS3Path(prefix || "")}${backupFileName}`;
|
||||||
? normalizeS3Path(prefix)
|
|
||||||
: `${volumeBackup.appName}/`;
|
|
||||||
const bucketDestination = `${effectivePrefix}${backupFileName}`;
|
|
||||||
const rcloneFlags = getS3Credentials(volumeBackup.destination);
|
const rcloneFlags = getS3Credentials(volumeBackup.destination);
|
||||||
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
|
||||||
const volumeBackupPath = path.join(VOLUME_BACKUPS_PATH, volumeBackup.appName);
|
const volumeBackupPath = path.join(VOLUME_BACKUPS_PATH, volumeBackup.appName);
|
||||||
|
|||||||
@@ -81,11 +81,8 @@ const cleanupOldVolumeBackups = async (
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = getS3Credentials(destination);
|
const rcloneFlags = getS3Credentials(destination);
|
||||||
const normalizedPrefix = prefix
|
const backupFilesPath = `:s3:${destination.bucket}/${volumeBackup.appName}/${normalizeS3Path(prefix || "")}`;
|
||||||
? normalizeS3Path(prefix)
|
const listCommand = `rclone lsf ${rcloneFlags.join(" ")} --include \"${volumeName}-*.tar\" ${backupFilesPath}`;
|
||||||
: `${volumeBackup.appName}/`;
|
|
||||||
const backupFilesPath = `:s3:${destination.bucket}/${normalizedPrefix}`;
|
|
||||||
const listCommand = `rclone lsf ${rcloneFlags.join(" ")} --include \"${volumeName}-*.tar\" :s3:${destination.bucket}/${normalizedPrefix}`;
|
|
||||||
const sortAndPick = `sort -r | tail -n +$((${keepLatestCount}+1)) | xargs -I{}`;
|
const sortAndPick = `sort -r | tail -n +$((${keepLatestCount}+1)) | xargs -I{}`;
|
||||||
const deleteCommand = `rclone delete ${rcloneFlags.join(" ")} ${backupFilesPath}{}`;
|
const deleteCommand = `rclone delete ${rcloneFlags.join(" ")} ${backupFilesPath}{}`;
|
||||||
const fullCommand = `${listCommand} | ${sortAndPick} ${deleteCommand}`;
|
const fullCommand = `${listCommand} | ${sortAndPick} ${deleteCommand}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user