Comprehensive Guide to Real Time Backup your Website to Dropbox

This is my last article about WordPress/Website/Hosting backup because in my opinion, it’s perfect solution to keep complete files/databases backups on the cloud and in real-time. As you known, I’ve moved to Digital Ocean for 9 months ago, then I configurated a very tiny VPS with low RAM to serving 5 websites with 10K pageviews per days.
If you’re following NARGA.NET and you’ve read some articles about automatic backup WordPress databasesclean and optimize WordPress databases

I’ve spent some time putting together a solution for automated database backups to a remote data storage or send it via email but it’s only good for database and small files but if you want use this way to backup complete website or in real time, it’s bad solution.
A good backup should have following criteria:

  • Backup your data, files as frequently as possible.
  • Give higher priority to critical data like database and web contents. Try to exclude temporary files.
  • Your backup should NOT be saved inside the same server.
  • Your backup should be retrievable and accessible anytime, anywhere.
  • Your backup should be compressed, if disk space or bandwidth is your concern.

The solution:

  • Have full permission of your hosting service to install and configure the backup scripts/services
  • A bash script is run daily/weekly through cron to dump and compress your files (include databases)
  • Always sync your files with third-party services like Dropbox, Copy, OneDrive

I won’t writing detail about How to setup your own server/VPS. I’m just tell you how to make it sync with cloud storage backup services.

Script to dump databases as files

Almost web server running LAMP, LEMP so I prefer you a bash and a php script to dump the mysql database.

Bash Scripts

#!/bin/bash

_file="backup-$(date +"%Y-%m-%d").sql.gz"

cd ~
mysqldump --user=username --password=password --host=hostname \
    --databases database1 database2 | gzip >$_file

PHP Script

$datestamp = date("Y-m-d");     // Current date to append to filename of backup file in format of YYYY-MM-DD

/* CONFIGURE THE FOLLOWING FOUR VARIABLES TO MATCH YOUR SETUP */
$dbuser = "username";     // Database username
$dbpwd = "password";     // Database password
$dbname = "database_name";     // Database name. Use --all-databases if you have more than one
$filename = "$datestamp.sql.gz";     // The name (and optionally path) of the dump file

$command = "mysqldump -u $dbuser --password=$dbpwd $dbname | gzip > $filename";
$result = passthru($command);

Setup cron jobs

Cron is a daemon that executes scheduled commands. You can setup cron job via command line or Hosting Control Panel.

Crontab Format

Commands are executed by cron when the minute, hour, and month of year fields match the current time, and when at least one of the two day fields (day of month, or day of week) match the current time.
A field may be an asterisk (*), which always stands for “first-last”. Ranges of numbers are allowed. Ranges are two numbers separated with a hyphen. The specified range is inclusive. For example, 8-11 for an “hours” entry specifies execution at hours 8, 9, 10 and 11.
Here is some special example:

String Meaning
@reboot Run once, at startup.
@yearly / @annually Run once a year 0 0 1 1 *
@monthly Run once a month 0 0 1 * *
@weekly Run once a week 0 0 * * 0
@daily Run once a day 0 0 * * *
@daily / @midnight Run once a day 0 0 * * *
@hourly Run once a hour 0 * * * *

An example of crontab format with commented fields is as follows:

# Minute   Hour   Day of Month       Month          Day of Week        Command    
# (0-59)  (0-23)     (1-31)    (1-12 or Jan-Dec)  (0-6 or Sun-Sat)                
    0        2          12             *                *            /backup-script

Get frustrated with Cron on your server? I found some online services that helps you create cron job with GUI selection.

Setup Cron Job on Hosting Control Panel

Hosting Control Panel like CPanel, ZPanel … that is very easy to setup, just click and choose.

Setup Dropbox on your server

The Dropbox daemon works fine on all 32-bit and 64-bit Linux servers. To install, run the following command in your Linux terminal.
32-bit

$ cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86" | tar xzf -

64-bit

$cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

Next, run the Dropbox daemon from the newly created .dropbox-dist folder.

$~/.dropbox-dist/dropboxd

Because we don’t install GUI on our server, that’s why we’re looking for the way to control Dropbox from command line. Fortunately, Dropbox provides their CLI script to control Dropbox from the command line.
Download this CLI script to control Dropbox from the command line. For easy access, put a symlink to the script anywhere in your PATH.

Getting Started

Start off by printing the help menu:

$ dropbox.py help
status       get current status of the dropboxd
help         provide help
puburl       get public url of a file in your dropbox
stop         stop dropboxd
running      return whether dropbox is running
start        start dropboxd
filestatus   get current sync status of one or more files
ls           list directory contents with current sync status
autostart    automatically start dropbox at login
exclude      ignores/excludes a directory from syncing

The default folder of Dropbox is ~/Dropbox, now we need following the Dropbox CLI setup wizard to setup your Dropbox account and folder position.

If you use Dropbox to sync your files, the hosting provider can access all your Dropbox files as they want. To prevent lossing your private information, you must encrypt your files before sync with Dropbox or just use a new Dropbox account.

Make your website synchronize with Dropbox in real-time

This is the way I’m using on Digital Ocean. I create a symlink of my vhost folder to ~/Dropbox then start Dropbox service, all my website files is synchronized with Dropbox in real time, I can upload/change/delete/move any files direct (without FTP/SFTP client) from my computer that’s using Dropbox too. Because I’m using Dropbox to manage my website files, I can turn off FTP service to decrease the server memory usage.
Here is my solution:

  1. Scheduling database backup script to create backup files per databases to specified folder. The backup folder is symlinked with Dropbox too. My VPS has 512MB RAM, I choose bash script and cron service and configurated it to run daily at 1:00 am. That’s about it folks. If everything has been setup correctly, the directories and databases configured should get backed up into a TAR file such as backup-year-month-date.sql.gz and uploaded to your Dropbox account.
  2. Create symlink per domain folder. For some reason, I’m using ZPanel to control my VPS, the website is located at /var/zpanel/hostdata/{zpanel-user}/public_html/{hosted-domain1}/ (change zpanel-user and hosted-domain1 with yours.
  3. If you using WordPress, you only need sync wp-config.php, .htaccess, /wp-content/themes, /wp-content/plugins and /wp-content/uploads or /wp-content/blog.dir folders. Try to exclude temporary files like wp-content/cache, wp-content/upgrade

Compress important files, send it to Dropbox then delete local file

Backup files sync to DropboxI found Dropbox-Uploader that is very useful script to help you backup website to Dropbox then delete backup file from server to save disk space. It’s not good as real-time synchronization way (in my opinion) but it’s worth to try.
Download and place Dropbox-Uploader script in the same folder (unless you change the reference in the script) with backup script above. Add some lines to run Dropbox-Uploader and delete local file after it’s uploaded to Dropbox.

#!/bin/bash

_file="backup-$(date +"%Y-%m-%d").sql.gz"

cd ~
mysqldump --user=username --password=password --host=hostname \
    --databases database1 database2 | gzip >$_file
./dropbox_uploader.sh -q upload $_file "/DB Backups/$_file"
rm $_file

Once all of this is set up, the script will automatically upload a backup of your database to your Dropbox at whatever interval you set.

Conclusion

Feel free to use the scripts and my solution provided. If you have any questions, do leave a comment and I will do my best to answer them.