How To Use Rsync to Backup Your VPS Files Off-Site
Tags: databackup, cloudskills, tutorial, ubuntu
Published: 2021-04-08 07:08:43

Sync is a simple yet powerful tool for system administrators. It allows you to easily copy and synchronize files from one server to another or from your local machine to a VPS server (off-site). Rsync is a smart tool that allows you to use a special algorithm so you can synchronize files as they are edited or added. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1yx04hkgccqsb5avsf7j.png)

There are two ways you can utilize the Rsync command to keep a backup of your production server on a remote backup server.
<ol>
<li>The sync method</li>
<li>The snapshot method</li>
</ol>

Both methods can be automated using a Cron job. However, you need to first set up the production server to login as a root in the backup server without a passphrase.

<h2>Prerequisites</h2>
<ol>
<li>A server running Ubuntu 18.04 – server A</li>
<li>A backup server running ubuntu 18.04 – server B</li>
</ol>

<a href="https://www.skysilk.com/cloud/pricing/#classId=Standard&section=2"> Deploy Ubuntu 18.04 </a>

<h2>Setting Up the Production Server to Login Into the Backup Server</h2>
Log in to your production server (server A) as root.

```
1 ssh root@server-A-IP
```

Create a keygen on your production server. (Make sure you create a passphraseless key).

```
1 ssh-keygen -t rsa -b 4096 -v
```

Copy the keys in your new backup server so that the production server is able to access the backup server as root.

```
1 ssh-copy-id server-B-IP
```

Once you run the above command, it will ask you for the root password of your backup server. This is a one-time process. You will type Server B’s root password only once. 

Test the authentication by logging in to a remote server inside the production server’s SSH shell.

```
1 ssh root@server-B-IP
```

You will be logged in to the backup server as root without needing a password. 

On successful authentication, try a few commands with sudo privileges. Once you’re done testing a few commands, logout from the backup server after creating a directory where you’ll be storing the backup. 

For this tutorial, we will use /root/backup as the backup location. Create this directory with the below command.

```
1 cd /root | mkdir backup


1 exit
```

<h2> The Sync Method </h2>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxy1d10ug74ebdrkwlq1.png)

In this method, the rsync command will first look for changes on the production server. The Rsync will process files that match one of the following conditions:

<ol>
<li>It is a new file added in the “source”</li>
<li>The file has recently been edited and does not match the file in the destination folder except the file name.</li>
<li>The file is removed from the “source”</li>
</ol>

So, before running the sync command, create a few files on “source”
Login to your production server as root. 

```
1 ssh root@server-A-IP
```

Create files named <b>1.html index.html</b> and <b>hello.html</b> with the below command. 

```
1 cd /var/www/html | touch 1.html index.html hello.html
```

To run the active sync once, run the following command on your production server.

```
1 rsync -azvP --delete /var/www/html/ root@serverB-ip:/root/backup/
```

The command returns a message like this. 

```
sending incremental file list

./

1.html

              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=2/4)

hello.html

              0 100%    0.00kB/s    0:00:00 (xfr#2, to-chk=1/4)

index.html

              0 100%    0.00kB/s    0:00:00 (xfr#3, to-chk=0/4)

sent 222 bytes  received 76 bytes  596.00 bytes/sec

total size is 0  speedup is 0.00
```

The next time you run this command again, the response should be something like this. 

```
sending incremental file list

sent 107 bytes  received 12 bytes  238.00 bytes/sec
 

total size is 0  speedup is 0.00
```

As you can see, rsync was smart enough to detect that there are no changes in the “source”. That is why, rsync did not transfer any file to the “destination”.

Test the sync by <b>creating 2.html</b> and <b>deleting hello.html</b> followed by the same rsync command.

```
1 cd /var/www/html | touch 2.html | rm -r hello.html


1 rsync -azvP --delete /var/www/html/ root@serverB-ip:/root/backup/
```

This time, rsync recognized the changes and synchronized the file that was added. Also, rsync deleted hello.html in the “destination” directory as it does not exist in the “source” anymore.

```
sending incremental file list

deleting hello.html

./

2.html

              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=1/4)

sent 150 bytes  received 52 bytes  134.67 bytes/sec

total size is 0  speedup is 0.00
```

To facilitate the synchronization, create a bash script so that you don’t have to type the whole command everytime you want to synchronize the files. 

```
1 cd /root


1 nano sync.sh
```

In the nano editor, paste the following and save. 

```
#!/bin/sh

#Automating the rsync to smart sync html folder to backup server

rsync -azvP –delete /var/www/html/ root@serverB-ip:/root/backup/
```


Save and exit the file using ctrl+X followed by Y and Enter. 

Now, everytime you want to manually synchronize the files to the backup server, run the following command. 

```
1 /root/sync.sh
```


<h2>Setting up Cronjob to Activate the Sync</h2>

Once you’re convinced that the Rsync command works as required, automate it with a new Cronjob. 

```
1 crontab -e
```

Choose the editor you want to use. Add the following line at the end of this file. 

```
1 30 20 * * 1 /root/sync.sh
```

The above cron will run every monday at 8:30 PM and sync all the files from source directory on the production server to the destination directory on your backup server. 

Save the file using ctrl+X followed by Y and Enter. 

<h2>The Snapshot Method</h2>

The sync method is not a scalable and effective method to keep backup of a production site. 

When you delete a file from the source destination, it will be automatically deleted from the destination directory as well when the cron runs. You can not retrieve the deleted file afterwards. 

To tackle this problem, you can create snapshots. You can set it up in the following manner.
<ol>
<li>Set up the rsync command to synchronize the files every morning at 9:30 AM</li>
<li>Create a snapshot of the site weekly on every monday at 10:30 AM.</li>
</ol>

This way, you will retain a copy of the source directory in a separate folder on the backup server. 

Instead of creating a snapshot and further transferring it to the backup server, create a bash script to do everything at once with a single line of code. 

Create a script 

```
1 cd /root


1 nano snapshot.sh
```


In the nano editor, paste the below content and change the following values. 

```
!/bin/sh
 
# Create a timestamp

date=date "+%Y-%m-%d-t-%H-%M-%S"

 
# Define the directory to retain on your production server


SOURCE=/var/www/html/
 
# Specify the destination folder on your backup VPS

DEST=/root/snapshots

# Execute rsync followed by cleanup

rsync -arvt -t \

  –delete \

  –link-dest=../current \

  $SOURCE root@server-B-IP:$DEST/backup-$ddate \

  && ssh root@server-B-IP \

  “rm -rf $DEST/current \

  && ln -s $DEST/backup-$date $DEST/current \

  && find $DEST -maxdepth 1 -type d -mtime +30 -exec rm -r {} +”
```


Change <b>server-B-IP</b> with your backup server’s public IP.  Save the file and exit using ctrl+X followed by Y and Enter.

Run this script with the following command

```
1 /root/snapshot.sh
```

When you run the command, it does the following:
<ul>
<li>It creates a snapshot of the “source” directory and further transfers it to the backup server in the specified destination folder</li>
<li>It creates a soft link “current” in the destination directory to the latest snapshot inside the directory.</li>
<li>It also checks for snapshots that are older than 30 days and further deletes it to conserve space on your backup server.</li>
</ul>

<h2>Automating the Snapshots and Sync with Cron job</h2>

To create an efficient backup of your files and sync the current version on the backup server, you can set up 2 cron jobs. 

Edit the crontab 

```
1 crontab -e
```

Choose the editor you want to use and add the following line at the end of this file. 

```
# synchronize the files from the production server to the backup server every morning at 9:30 am

30 9 * * * /root/sync.sh


 
# create a snapshot of the source directory weekly on every Monday

30 10 * * 1 /root/sync.sh
```


Save the file and exit using <b>ctrl+X</b> followed by <b>Y</b> and <b>Enter</b>.

<h2>Conclusion</h2>

At this stage you have set up a daily off-site active sync along with weekly off-site snapshots.

You can do much more with Rsync command itself and automate it with bash scripts and cron jobs. 
</body>
</html>