Merge pull request #5025 from Dokploy/fix/backup-double-dump-4222

fix: run database dump once per backup and clean up partial uploads on failure
This commit is contained in:
Mauricio Siu 2026-08-09 12:11:28 -06:00 committed by GitHub
commit 4791863ff9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 23 additions and 38 deletions

View File

@ -37,11 +37,10 @@ export const runComposeBackup = async (
try {
const rcloneFlags = getS3Credentials(destination);
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const backupCommand = getBackupCommand(
backup,
rcloneCommand,
rcloneFlags,
rcloneDestination,
deployment.logPath,
);
if (compose.serverId) {

View File

@ -36,12 +36,10 @@ export const runLibsqlBackup = async (
try {
const rcloneFlags = getS3Credentials(destination);
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const backupCommand = getBackupCommand(
backup,
rcloneCommand,
rcloneFlags,
rcloneDestination,
deployment.logPath,
);
if (libsql.serverId) {

View File

@ -35,11 +35,10 @@ export const runMariadbBackup = async (
try {
const rcloneFlags = getS3Credentials(destination);
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const backupCommand = getBackupCommand(
backup,
rcloneCommand,
rcloneFlags,
rcloneDestination,
deployment.logPath,
);
if (mariadb.serverId) {

View File

@ -32,11 +32,10 @@ export const runMongoBackup = async (mongo: Mongo, backup: BackupSchedule) => {
try {
const rcloneFlags = getS3Credentials(destination);
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const backupCommand = getBackupCommand(
backup,
rcloneCommand,
rcloneFlags,
rcloneDestination,
deployment.logPath,
);

View File

@ -33,12 +33,10 @@ export const runMySqlBackup = async (mysql: MySql, backup: BackupSchedule) => {
try {
const rcloneFlags = getS3Credentials(destination);
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const backupCommand = getBackupCommand(
backup,
rcloneCommand,
rcloneFlags,
rcloneDestination,
deployment.logPath,
);

View File

@ -36,12 +36,10 @@ export const runPostgresBackup = async (
try {
const rcloneFlags = getS3Credentials(destination);
const rcloneDestination = `:s3:${destination.bucket}/${bucketDestination}`;
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const backupCommand = getBackupCommand(
backup,
rcloneCommand,
rcloneFlags,
rcloneDestination,
deployment.logPath,
);
if (postgres.serverId) {

View File

@ -259,11 +259,14 @@ export const generateBackupCommand = (backup: BackupSchedule) => {
export const getBackupCommand = (
backup: BackupSchedule,
rcloneCommand: string,
rcloneFlags: string[],
rcloneDestination: string,
logPath: string,
) => {
const containerSearch = getContainerSearchCommand(backup);
const backupCommand = generateBackupCommand(backup);
const rcloneCommand = `rclone rcat ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
const rcloneDeleteCommand = `rclone deletefile ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
logger.info(
{
@ -279,33 +282,24 @@ export const getBackupCommand = (
set -eo pipefail;
echo "[$(date)] Starting backup process..." >> ${logPath};
echo "[$(date)] Executing backup command..." >> ${logPath};
CONTAINER_ID=$(${containerSearch})
CONTAINER_ID=$(${containerSearch});
if [ -z "$CONTAINER_ID" ]; then
echo "[$(date)] ❌ Error: Container not found" >> ${logPath};
exit 1;
fi
fi;
echo "[$(date)] Container Up: $CONTAINER_ID" >> ${logPath};
echo "[$(date)] Starting backup and upload to S3..." >> ${logPath};
# Run the backup command and capture the exit status
BACKUP_OUTPUT=$(${backupCommand} 2>&1 >/dev/null) || {
UPLOAD_OUTPUT=$({ ${backupCommand} | ${rcloneCommand}; } 2>&1 >/dev/null) || {
echo "[$(date)] ❌ Error: Backup failed" >> ${logPath};
echo "Error: $BACKUP_OUTPUT" >> ${logPath};
exit 1;
}
echo "[$(date)] ✅ backup completed successfully" >> ${logPath};
echo "[$(date)] Starting upload to S3..." >> ${logPath};
# Run the upload command and capture the exit status
UPLOAD_OUTPUT=$(${backupCommand} | ${rcloneCommand} 2>&1 >/dev/null) || {
echo "[$(date)] ❌ Error: Upload to S3 failed" >> ${logPath};
echo "Error: $UPLOAD_OUTPUT" >> ${logPath};
${rcloneDeleteCommand} >/dev/null 2>&1 || true;
exit 1;
}
};
echo "[$(date)] ✅ Upload to S3 completed successfully" >> ${logPath};
echo "[$(date)] ✅ Backup uploaded to S3 successfully" >> ${logPath};
echo "Backup done ✅" >> ${logPath};
`;
};