Blog / Others/ Ultimate Guide: Daily Automated VPS Backup with rsync

Ultimate Guide: Daily Automated VPS Backup with rsync

终极版rsync-VPS每日定时同步自动备份方法

Introduction

This guide details a method for setting up daily automated backups between two VPS servers using rsync. We assume VPS A is the production server hosting the website, and VPS B is the backup server. Both are running CentOS. The goal is for VPS B to automatically pull website files and database backups from VPS A on a schedule.

Part 1: VPS A (Source Server) Setup

VPS A acts as the rsync server. We will configure the rsync daemon and set up a MySQL backup script.

1. Install rsync

Install rsync using yum:

yum -y install rsync

For traditional daemon mode (common on older CentOS), add it to startup:

echo 'rsync --daemon' >> /etc/rc.d/rc.local

Note: For modern CentOS/RHEL 7+ using systemd, it's better to use systemctl enable rsyncd if using the packaged service. This guide uses the traditional daemon method.

2. Set rsync Authentication Password

Create a password file with the format 'username:password':

echo 'your_username:your_password' > /etc/rsyncd.scrt
chmod 600 /etc/rsyncd.scrt

This username and password will be used by VPS B to connect.

3. Configure rsync Service

Edit the configuration file /etc/rsyncd.conf:

uid = root
gid = root
use chroot = no
read only = yes
max connections = 10

port = 873
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
#log file = /var/log/rsync.log
log format = %t %a %m %f %b
syslog facility = local3
timeout = 300

[www]
path = /var/www/
comment = Website Data
ignore errors
read only = yes
list = no
auth users = your_username
secrets file = /etc/rsyncd.scrt
exclude from = /etc/rsync_exclude.txt
hosts allow = VPS_B_IP_ADDRESS
hosts deny = *

Key Configuration Points:

  • [www]: Module name, specified by the client during connection.
  • path: Source directory to synchronize.
  • auth users: Allowed username for authentication.
  • hosts allow: Must be replaced with the real IP address of VPS B for security.

4. Define Exclusion List

Create an exclusion file /etc/rsync_exclude.txt. List directories (relative to the path) that should not be backed up, one per line:

cache/
temp/

5. Create rsync Restart Script

Create a script /root/rsyncd_restart.sh to restart the rsync daemon:

#!/bin/bash
kill -9 `cat /var/run/rsyncd.pid`
rm -f /var/run/rsyncd.pid
rm -f /var/run/rsync.lock
rsync --daemon

Make it executable:

chmod 600 /root/rsyncd_restart.sh
chmod +x /root/rsyncd_restart.sh

You can now restart the service with /root/rsyncd_restart.sh.

6. Configure MySQL Automatic Backup Script

Create a script /root/mysql_backup.sh to back up multiple databases and clean old backups:

#!/bin/bash
# Configuration
mysql_user="USER"
mysql_password="PASSWORD"
mysql_host="localhost"
mysql_port="3306"
mysql_charset="utf8mb4"
backup_db_arr=("db1" "db2")
backup_location=/var/www/mysql
expire_backup_delete="ON"
expire_days=3

# Internal variables
backup_time=$(date +%Y%m%d%H%M)
backup_Ymd=$(date +%Y-%m-%d)
backup_dir=$backup_location/$backup_Ymd

# Check if MySQL is running
mysql_ps=$(ps -ef | grep mysqld | grep -v grep | wc -l)
mysql_listen=$(netstat -an | grep LISTEN | grep ":$mysql_port" | wc -l)
if [[ $mysql_ps -eq 0 ]] || [[ $mysql_listen -eq 0 ]]; then
    echo "ERROR: MySQL is not running! Backup stopped."
    exit 1
fi

# Test connection
mysql -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password -e "SELECT 1" > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "ERROR: Can't connect to MySQL server! Backup stopped."
    exit 1
fi

# Start backup
if [ "${#backup_db_arr[@]}" -gt 0 ]; then
    mkdir -p $backup_dir
    for dbname in "${backup_db_arr[@]}"
    do
        echo "Backing up database: $dbname"
        mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password 
        --single-transaction --routines --triggers --default-character-set=$mysql_charset $dbname | gzip > $backup_dir/${dbname}-${backup_time}.sql.gz
        if [ $? -eq 0 ]; then
            echo "Database $dbname backed up successfully."
        else
            echo "ERROR: Failed to backup database $dbname"
        fi
    done
else
    echo "ERROR: No database specified for backup."
    exit 1
fi

# Clean expired backups
if [ "$expire_backup_delete" == "ON" ] && [ -n "$backup_location" ]; then
    find $backup_location -type d -mtime +$expire_days -exec rm -rf {} ; 2>/dev/null
    echo "Expired backups older than $expire_days days deleted."
fi

echo "All databases backed up successfully."

Make it executable:

chmod 600 /root/mysql_backup.sh
chmod +x /root/mysql_backup.sh

Add it to crontab to run daily at 00:00:

0 0 * * * /root/mysql_backup.sh

VPS A setup is now complete. Website files are available via the rsync module, and database backups are generated in /var/www/mysql/, which is within the rsync sync path.

Part 2: VPS B (Backup Server) Setup

VPS B acts as the rsync client, pulling data from VPS A on a schedule.

1. Install rsync

yum -y install rsync

The client does not need a persistent service, so no startup configuration is required.

2. Set rsync Password File

Create a file containing only the password (not 'username:password'):

echo 'your_password' > /etc/rsync.pass
chmod 400 /etc/rsync.pass

3. Test Synchronization

Create a local storage directory:

mkdir -p /var/rsync/

Run a test sync command:

rsync -avzP --delete --password-file=/etc/rsync.pass username@VPS_A_IP::www /var/rsync/website_backup/

Command Parameter Explanation:

  • -avzP: Archive mode, verbose, compress, show progress.
  • --delete: Makes the target directory an exact mirror of the source.
  • --password-file: Specifies the password file path.
  • username@VPS_A_IP::www: Connects to VPS A's rsync service using the 'www' module.
  • The last argument is the local storage path.

4. Add to Crontab

Edit crontab to run the sync daily at 00:30 (after MySQL backup completes at 00:00):

30 0 * * * rsync -avzP --delete --password-file=/etc/rsync.pass username@VPS_A_IP::www /var/rsync/website_backup/ > /dev/null 2>&1

Output is redirected to /dev/null to avoid unnecessary log emails.

Summary and Extensions

You have now established an automated backup system from VPS A to VPS B, covering both website files and databases.

For enhanced data security, consider adding a "VPS C" to sync from VPS B, creating a geographically separate second backup. The configuration would be similar to VPS B pulling from A.

Important Notes:

  • Ensure the firewall on VPS A allows traffic on port 873 (or your custom rsync port).
  • Set strict permissions on password files to prevent leaks.
  • Regularly check backup logs and verify backup file integrity.
  • For modern Linux distributions, consider using systemd services or timers to manage rsync and scheduled tasks.

Post a Comment

Your email will not be published. Required fields are marked with *.