Using Git as a Lightweight Backup Solution for Development Servers: A Practical Guide


3 views

While Git isn't traditionally designed as a backup tool, its version control capabilities make it surprisingly effective for certain backup scenarios. For development servers where:

  • You need quick, incremental backups
  • Complete disaster recovery isn't critical
  • You want to avoid complex backup systems
  • Version history would be beneficial

Git offers several advantages over conventional backup methods for these use cases.

Here's how to set up a basic Git-based backup system:

# Initialize repository at root
sudo cd /
sudo git init

# Create basic .gitignore to exclude system directories
echo "/proc/" >> .gitignore
echo "/dev/" >> .gitignore
echo "/sys/" >> .gitignore
echo "/run/" >> .gitignore
echo "/tmp/" >> .gitignore

# Initial commit
sudo git add .
sudo git commit -m "Initial server backup"

Create a cron job to handle regular updates:

# Add to crontab -e
0 * * * * cd / && /usr/bin/git add -A && /usr/bin/git commit -m "Hourly backup $(date)"

For more sophisticated handling:

#!/bin/bash
cd /
git add -A
if git diff-index --quiet HEAD --; then
    echo "No changes detected"
else
    git commit -m "Auto-backup $(date +%Y-%m-%d_%H:%M:%S)"
    # Optional: Push to remote
    git push backup_remote main
fi

For better performance with large files:

# Configure Git for better handling of large repos
git config --global core.compression 9
git config --global pack.depth 50
git config --global pack.windowMemory 256m

To add redundancy, set up a remote repository:

# On backup server:
mkdir /backups/dev-server.git
cd /backups/dev-server.git
git init --bare

# On production server:
git remote add backup ssh://user@backup.server:/backups/dev-server.git
git push --set-upstream backup main

To restore from backup:

# On new server:
git clone ssh://user@backup.server:/backups/dev-server.git /
  • Not suitable for binary files that change frequently
  • No built-in compression like dedicated backup tools
  • File permissions aren't preserved by default
  • Database backups require separate handling

For better handling of large files:

sudo apt-get install git-annex
cd /
git init
git annex init "Server backup"
git annex add .
git commit -m "Initial annex backup"

For development environments where formal backup solutions seem overkill, Git offers an intriguing alternative. Many developers already use Git daily, making it a familiar tool that can serve dual purposes.

Here's a minimal setup to version your entire server (excluding special directories):

# Initialize repository at root
cd /
sudo git init

# Create basic .gitignore
echo "/proc/*" >> .gitignore
echo "/dev/*" >> .gitignore
echo "/sys/*" >> .gitignore
echo "/run/*" >> .gitignore
echo "/tmp/*" >> .gitignore

# Initial commit
sudo git add .
sudo git commit -m "Initial server state"

To make this solution robust, consider these enhancements:

# Move .git to separate storage
sudo mkdir /mnt/backup_drive/server_git
sudo mv /.git /mnt/backup_drive/server_git
sudo ln -s /mnt/backup_drive/server_git/.git /.git

# Automated update via cron
(crontab -l 2>/dev/null; echo "0 * * * * cd / && sudo git add -A && sudo git commit -m 'Auto-commit: $(date)'") | crontab -

Git isn't optimized for large binaries, but these strategies help:

# Configure Git for better binary handling
git config --global core.compression 9
git config --global pack.packSizeLimit 1g
git config --global pack.windowMemory 1g

Restoring from a Git backup is straightforward:

# For complete restoration
cd /destination
git clone file:///mnt/backup_drive/server_git/.git .

# For specific file recovery
git checkout COMMIT_HASH -- path/to/file

While useful for development environments, remember:

  • Git doesn't handle file permissions perfectly
  • Database files require separate handling
  • Frequent changes can bloat the repository
  • Not a substitute for proper disaster recovery solutions

For better large file support:

sudo apt-get install git-annex
cd /
sudo git init
sudo git annex init "Server Backup"
sudo git annex add .
sudo git commit -m "Initial annex commit"