This will work in most VPS and shared hosting services based on Linux.
It is known to work with Bluehost and A2 Hosting, both of these hosting services comply with all requirements.
- Creates local compressed backups of files and databases
- Works with any type of web service (PHP, Node, ASP, Perl, etc...)
- Option to limit the amount of backups to keep
- Sync to any remote or cloud service using rclone
- Pure Bash script: no PHP, no Python, no NodeJS
mysqldump
: part of MySQL or MariaDB package, for database backupscurl
: to download the files, included in most Linux distrosgzip
: to create archives, included in most Linux distrostar
: to create archives, included in most Linux distros
- Install and configure a local copy of rclone
setup_rclone.sh
. If you don't have access to the shell, you can create the config file elsewhere and then upload to the scripts root folder.
#!/bin/bash
# Install/update a local instance of rclone inside the script folder and run "rclone config"
echo Deleting old version...
rm -r rclone
echo Downloading the new version....
curl -O https://downloads.rclone.org/rclone-current-linux-amd64.zip
echo Unzipping downloaded file...
unzip rclone-current-linux-amd64.zip
echo Organizing folders...
rm rclone-current-linux-amd64.zip
mv rclone-* rclone
echo Running rclone config...
./rclone/rclone --config=rclone.conf config
echo DONE!
- Configure the script:
~/wiki-backup/autobackup.sh
#!/bin/bash
#----------------------------------------------------------
# PHP + MySQL backup script
# By Daniel B.P. ([email protected])
# Version 1: 09/03/2025
#----------------------------------------------------------
#Configuration
filesSource=~/public_html/my_site/wiki #source dir
filesDest=~/wiki-backup/backups/files #local archive destination
filesBkpKeep=4 #4 equals 3 files to keep (n-1)
dbHost=localhost #source database host name or IP
dbPort=3306 #source database port number
dbName=site_wiki #source database name
dbUser=site_wiki #source dabase user name
dbPass=PASSWORD_PASSWORD_PASSWORD
dbDest=~/wiki-backup/backups/db #local archive destination
dbBkpKeep=5 #5 equals 4 files to keep (n-1)
rcloneDir=~/wiki-backup/rclone #leave like this if using the setup script
rcloneConfig=~/wiki-backup/rclone.conf #this file should be created after running the setup script
rcloneRemoteName=FTP-BKP #this is the name of the remote given in rclone config
filesRemoteDest=/files #remote files archive destination
dbRemoteDest=/db #remote DB archive destination
#----------------------------------------------------------
# Welcome
echo --------------------------
echo PHP + MySQL backup script
echo "$(date +'%d/%m/%Y %H:%M')"
echo --------------------------
# Set filenames
timestamp=$(date +%F-%H%M%S)
fileZipName="${timestamp}_files.tar.gz"
sqlZipName="${timestamp}_db.sql.gz"
# Prepare directories
mkdir -p $filesDest
mkdir -p $dbDest
# Backup files to local folder
echo Backup files...
tar -czf $filesDest/$fileZipName $filesSource
# Backup database to local folder
echo Backup database...
mysqldump -P $dbPort -h $dbHost -u $dbUser -p$dbPass $dbName \
| gzip > $dbDest/$sqlZipName
# Purge old backups
echo Purge old backups...
# Cleanup files
find $filesDest -maxdepth 1 -type f -printf '%Ts\t%p\n' \
| sort -rn \
| tail -n +$filesBkpKeep \
| cut -f2- \
| xargs -r rm
# Cleanup databases
find $dbDest -maxdepth 1 -type f -printf '%Ts\t%p\n' \
| sort -rn \
| tail -n +$dbBkpKeep \
| cut -f2- \
| xargs -r rm
# Sync remote
echo Remote sync...
# Sync files
$rcloneDir/rclone sync $filesDest \
$rcloneRemoteName:$filesRemoteDest \
--verbose --config="${rcloneConfig}"
#alternative version with copy (infinite uploads)
#$rcloneDir/rclone copy $filesDest \
#$rcloneRemoteName:$filesRemoteDest \
#--verbose --ignore-existing --config="${rcloneConfig}"
# Sync databases
$rcloneDir/rclone sync $dbDest \
$rcloneRemoteName:$dbRemoteDest \
--verbose --config="${rcloneConfig}"
# Done
echo DONE!
- Configure CRON
Every week
0 0 * * 0 /home1/site/wiki_backup/autobackup.sh