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.
- Crontab
- CronSandbox
- Cron Maker
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.
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:
- 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 asbackup-year-month-date.sql.gz
and uploaded to your Dropbox account. - 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}/
(changezpanel-user
andhosted-domain1
with yours. - 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 likewp-content/cache
,wp-content/upgrade
…
Compress important files, send it to Dropbox then delete local file
I 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.