The importance of backups, can never be stressed enough, however backing up websites, and their databases from a hosting server, can be challenging in some cases. Sure you can do periodic sql dumps using phpmyadmin, and transfer the website files using winscp or any other scp client. However, experience has shown, that manual backups are a boring task, and sooner or later, you will start to slack, and “forget” to do a backup every now and again, and before you even know it, your last backup is from a month ago … if not more, and you only realise, when you actually need to restore !
Even worse, manual backups using the methods mentioned above, are not differential and tend to hurt bandwidth usage by copying all the files every time they run.
What if we could create a script to do the dirty work for us and backup the databases, and the website files, with one single command, and while it also copy only the files that have actually changed since our last backup ?
Windows 10 Ubuntu Bash
One of the coolest features (for us computer geeks that is) of Windows 10, is the Ubuntu Bash Linux shell. Before it came along, we used to rely on programs like cygwin to use the power of bash scripting on Windows, however for all its usefulfulness, cygwin was cumbersome to install and maintain, and unlike Ubuntu Bash on Windows, which is a Windows Subsystem for Linux ,cygwin is an emulation at best. Having said everything cygwin was and still remains a fantastic set of tools, which is still very valid.
The Ubuntu Bash Linux shell on the other hand, is a fully fletched Linux shell, inside a windows command prompt. Unlike cygwin, it is not an emulator, and if you really wanted to, you could even run an X-Server on your windows machine, and invoke Linux binaries inside the shell which would use your X-Server as their display, thus running GUI-Based Linux applications inside your windows. However all this goes beyone the scope of this tutorial. What we are after here is a small bash script to backup our website files and databases, located on our VPS or Shared hosting server.
Before we begin, here are the assumptions :-
- You are using windows 10, and have installed Ubuntu Bash (If not you may follow this guide)
- You have ssh access to your vps / shared hosting server.
- You have enough space on your windows machine to copy all the website files from your server including the sql databases.
- You have an sql user which has access to ALL databases on the server
Create passwordless ssh access from your machine to your server
- Start Ubuntu bash shell by typing “bash” in your Windows 10 command prompt
C:\>bash [email protected]:/mnt/c#
- Install the Ubuntu rsync package
[email protected]:/mnt/c# apt-get install rsync
[email protected]:/mnt/c# apt-get install rsync Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed rsync 0 to upgrade, 1 to newly install, 0 to remove and 105 not to upgrade. Need to get 284 kB of archives. After this operation, 653 kB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu/ trusty-updates/main rsync amd64 3.1.0-2ubuntu0.2 [284 kB] Fetched 284 kB in 0s (467 kB/s) Selecting previously unselected package rsync. (Reading database ... 25606 files and directories currently installed.) Preparing to unpack .../rsync_3.1.0-2ubuntu0.2_amd64.deb ... Unpacking rsync (3.1.0-2ubuntu0.2) ... Processing triggers for man-db (188.8.131.52-1ubuntu1) ... Processing triggers for ureadahead (0.100.0-16) ... Setting up rsync (3.1.0-2ubuntu0.2) ... [email protected]:/mnt/c#
In order to copy the files from our web server, we will be using rsync over ssh. We will also be using ssh to dump the databases. As you may already know, ssh requires password authentication, which would make script automation impractical if not impossible, since we would need to enter the ssh password multiple times during the script execution.
For this reason, we will use a private/public key pair for password-less ssh between our machine and the web server. Obviously, do this ONLY on a machine you trust, which only you have access too, and if you understand the security implications.
The first step, for password-less ssh login is to create a key pair.
Issue the command “ssh-keygen -t rsa”, when asked for a passphrase, just press the enter key (leaving it blank)
[email protected]:~# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): myserver Enter passphrase (empty for no passphrase):[press enter] Enter same passphrase again:[press enter again] Your identification has been saved in myserver. Your public key has been saved in myserver.pub. The key fingerprint is: 8a:a2:21:ff:02:da:bb:56:82:aa:2f:ca:3f:aa:06:5c [email protected] The key's randomart image is: +--[ RSA 2048]----+ | | | aaA..= | | Eaa+ . | | | | .o S | |. . o= + | |o= E. + + . | |*oB. = | |O+o. . | +-----------------+
Next we need to create (unless this already exists) a “.ssh” directory under your home directory on your web server by issuing the following command :-
ssh -p 22 [email protected] mkdir .ssh
Note : “-p 22” needs to be modified according to which port you use to ssh to your server.
[email protected]:~#ssh -p 22 [email protected] mkdir ~/.ssh [email protected]'s password: [Your Server Password Here]
This command can either return nothing (meaning the directory was successfully created) or something like “mkdir: cannot create directory ‘.ssh’: File exists“, which means there is already an “.ssh” directory in the home directory of the user.
We now need to upload the public key we just created to our server, and make them accessible only to our user (chmod 640).
[email protected]:~#cat ~/.ssh/myserver.pub | ssh -p 22 [email protected] 'cat >> ~/.ssh/authorized_keys' [email protected]'s password: [Your Server Password Here]
[email protected]:~#ssh -p 3516 [email protected] "chmod 640 ~/.ssh/authorized_keys" [email protected]'s password:[Your Server Password Here]
Next let’s create a config file, to further simplify things for us.
On your Windows 10 machine create a file called ~/.ssh/config and add the below configuration to it. (Change the parts in red to suite your setup)
Host yourdomain.com HostName yourdomain.com Port 22 User Username IdentityFile ~/.ssh/myserver <-- This is the name of the private key we created above
Finally issue the command chmod 600 ~/.ssh/config and chmod 600 ~/.ssh/myserver
[email protected]:~#chmod 600 ~/.ssh/config [email protected]:~#chmod 600 ~/.ssh/myserver
If all went well, issuing the command “ssh yourdomain.com” should without any further input from your end, login directly to your sever.
[email protected]:~#ssh yourdomain.com Last login: Thu Feb 16 19:19:37 2017 from 184.108.40.206 [[email protected] ~]$
If after issuing “ssh yourdomain.com” you get an error about “Bad owner or permission on …“, check the ownership and permission of the ~/.ssh/config file and ~/.ssh/myserver key files
In part 2 of this tutorial, we will write the actual script that will export all databases, and do the differential copy of all the website files.