Simplifying Legacy App Deployment with rsync Backup Magic

Table of Contents

The Pain of Legacy Deployment

So lately I’ve been working on another Jenkins pipeline, and there’s this service - a scheduler that still runs vanilla style on traditional VMs without containers. Despite many reasons I can’t win that containerization fight yet, I needed to make this vanilla app deployment at least a bit more bearable with CI/CD.

This scheduler is a JAR file with its dependencies, updated regularly. But the deployment flow? Pure torture. I had to copy files one by one, backup one by one. I know if I could just get permission to containerize this thing, the suffering would end. But work must go on.

The rsync Revelation

That’s when I got the idea to use rsync, and this time I dove deeper. I discovered these game-changing parameters: -b and --backup-dir. These are incredibly helpful because they let you backup only the updated files - no storage hogging, and with a little tweak to the backup-dir, I can create backup folders with datetime-stamped names.

Just with one command - no long bash scripts needed, just a simple one-line solution that eases the torture significantly.

The Magic Command

Here’s the beauty of it:

rsync -avb --backup-dir=/path/to/backups/$(date +%Y-%m-%d_%H%M%S) /source/path/ /destination/path/

Let me break this down:

  • -a: Archive mode (preserves permissions, timestamps, etc.)
  • -v: Verbose output
  • -b: Create backups of files that are being updated
  • --backup-dir: Specify where to store the backup files
  • $(date +%Y-%m-%d_%H%M%S): Creates a timestamp folder like 2025-09-24_203045

Why This Works So Well

Before rsync:

# The old torturous way
cp scheduler.jar scheduler.jar.backup.$(date +%Y-%m-%d)
cp lib1.jar lib1.jar.backup.$(date +%Y-%m-%d)
cp lib2.jar lib2.jar.backup.$(date +%Y-%m-%d)
# ... repeat for every single file
# Then copy new files
cp /new/scheduler.jar /production/
cp /new/lib1.jar /production/
# ... you get the idea

After rsync:

# One beautiful command
rsync -avb --backup-dir=/backups/$(date +%Y-%m-%d_%H%M%S) /staging/scheduler/ /production/scheduler/

Advanced rsync Deployment Script

For even more control, here’s a slightly enhanced version:

#!/bin/bash

TIMESTAMP=$(date +%Y-%m-%d_%H%M%S)
SOURCE="/path/to/staging/scheduler/"
DEST="/path/to/production/scheduler/"
BACKUP_DIR="/path/to/backups/$TIMESTAMP"

echo "Starting deployment at $TIMESTAMP"
echo "Backup directory: $BACKUP_DIR"

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Sync with backup
rsync -avb --backup-dir="$BACKUP_DIR" "$SOURCE" "$DEST"

echo "Deployment completed. Backups stored in: $BACKUP_DIR"

# Optional: Clean up old backups (keep last 10)
find /path/to/backups -maxdepth 1 -type d -name "20*" | sort -r | tail -n +11 | xargs rm -rf

Key Benefits

  1. Single Command: No more repetitive copy operations
  2. Automatic Backups: Only changed files are backed up
  3. Timestamped Backups: Easy to identify when changes were made
  4. Storage Efficient: Only modified files consume backup space
  5. Rollback Ready: Easy to restore from timestamped backups

Rollback Made Simple

If something goes wrong, rolling back is straightforward:

# List available backups
ls -la /path/to/backups/

# Restore from specific backup
rsync -av /path/to/backups/2025-09-24_203045/ /production/scheduler/

The Reality Check

Look, I know this isn’t the ideal solution. Containers would solve this problem elegantly. But sometimes you work with what you have, and rsync with backup capabilities transforms a painful manual process into a manageable one-liner.

This approach has saved me countless hours and reduced deployment stress significantly. Sometimes the best solution isn’t the most modern one - it’s the one that works with your constraints and makes your life easier.

Conclusion

While I’m still fighting the good fight for containerization, rsync has become my deployment ally for legacy systems. The combination of -b and --backup-dir with timestamp folders turns deployment torture into a manageable process.

One command, automatic backups, easy rollbacks - sometimes simple solutions are the most powerful ones.