So I was planning to go away for a long time and a big relocation was coming up. This meant my local systems would be shut down and my personal websites (like this blog) would go offline for an extended period of time. Now, we simply couldn’t agree with that. The solution was to fail them over to somewhere that was cheap and did not need a yearly commitment to work.
My first choice was getting a VPS (Virtual Private Server) from a hosting service. But these were too costly for the 15-30 day period I wanted it for. The next obvious choice was to use a cloud VM. It would be external, and it would be pay-for-use. So then, which cloud? I had already found the experience with Microsoft’s Azure a much better experience compared to both Amazon’s AWS (dauntingly detailed control panels) and Google Cloud (completely un-intuitive). This left me only Azure as a choice.
I had the virtual network and gateway setup from my previous dalliance still active. I had since uploaded a certificate key file and enabled the “Point to Site VPN” as well. This gives you a VPN client app to download. You run this app at your end to create a VPN connection from your Windows system to the cloud’s gateway. This is much cleaner than using the RRAS based setup described in my earlier article and also works on non-Server OS machines, or where you do not want to install RRAS.
Step 1 – Create VM
The first step is obviously to create a VM on the cloud. I decided against going with “web apps”, because I wanted both finer control and to be able to run multiple things. For one, I also host my own DNS — where would I put that in a web app scenario? I was faced with two choices – a Windows VM or a Linux one. To help me choose, I initially created two VMs. Whichever one I could get WordPress up and running first would win out, with the other getting destroyed.
No prizes for guessing, but the Linux VM won out. I chose Ubuntu Linux, partly because I had more experience on that compared to both SuSE and CentOS that were the other choices) and partly because my latest favorite because of the Raspbian OS, the Debian, is not part of the list. Given that I had already run through the Linux prep recently when I did the Raspberry Pi set up, I had all the necessary commands and configuration files ready to go right here on this blog! I ran through that set up, clubbing several commands like the apt-get installs together to speed it up even further.
To finish up, using WinSCP, I logged on to the new VM and copied over the necessary configuration files. I had to do a couple of edits, like replacing the IP addresses in the website virtual host configuration files for Apache and in the BIND9 DNS configuration files.
Important! One key change I had to make was that in the Apache virtual host conf files, I had to edit the <Directory>
directives to make them look as below:
<Directory "/web/foo">
AllowOverride All
Require all granted
</Directory>
The “Require all granted” is absolutely required in Apache 2.4 upwards. Without this directive, you will end up getting a strange error saying you do not have access to the “/” folder. Even running the CHMOD
and CHOWN
commands will not fix that error. This change needs to be made to the .conf file of every site you have enabled.
Don’t forget to enable the sites and then reload or restart Apache.
At the end of this, I had BIND, Apache and MySQL up and running on the VM. BIND was answering queries locally or when specifically directed at it from a remote machine’s nslookup. Apache was able to serve the default website and sent 404s for my websites (I still had not transferred the WordPress files over!). I could log on to MySQL using the credentials setup for both WordPress and the MySQL root account.
Step 2 – Set Up MySQL Databases
Using WinSCP, I copied over the WordPress MySQL Database daily backup files to the /root folder (remember I am logged in as root at this stage). Then from my PuTTy terminal, I imported these files to the MySQL on the Azure VM.
In my case, there were no further changes to the DB since the last backup, so I could simply use that instead. The correct way would be to:
- Turn off the live website web server (IIS/Apache/etc)
- Take the backup
- Turn off MySQL
- Copy the files to the new system and import them
Since you are failing it over, you would not be starting the web server or the MySQL service on the source machine.
I had one small hiccup here that my daily backups were configured to NOT create the databases or the tables. It contained only the data. So I had to first create a .sql file with the structure only, copy that over, import it and then import the rest of the daily backup .sql files.
Step 3 – Sync the Website Files to the Azure VM
The next thing that remained was to copy over all the WordPress files (for my websites) to the Azure VM. At first, I tried to do it over the Internet using WinSCP. However, there are SO MANY files in a regular WordPress install, not to mention the content you have uploaded to the wp-content folder, that it takes a really long time. So, I decided to switch to “rsync” and pull it from the Azure VM.
Using the VPN client package, I created a VPN connection from one of my local Windows machines to the Azure gateway. I shared out the actual WordPress site files on the Windows machine. And, I also needed to open up the SMB ports temporarily to facilitate the Ubuntu VM to talk to my local system NFS.
I now tried to mount the Windows share from the Azure VM:
# mkdir /network
# mount -t cifs -o ro,user=Administrator@10.0.0.5 /network //10.0.0.5/wordpress
10.0.0.5 was the IP address of my local machine over the Azure VPN. But that did not work. MOUNT simply errored out with the infamous “error 115”. After a few tries of this and that, I gave up the VPN idea. I would have to do the rsync over the Internet.
Now from the Azure VM, I mounted the share and then ran rsync:
# mount -t cifs -o ro,user=Administrator@10.0.0.5 /network //<public IP of my local system>/wordpress
# rsync -arv /network/* /web
That worked. But it took about 10 minutes to finish copying everything and I took a break.
Remember to turn off the SMB ports on your firewall or your on-prem system would be left open to attacks!
Step 4 – Switch Over Public DNS, and Azure
The penultimate step was to switch over the DNS records to allow the new VM to be the master. I headed over to my DNS registrar and updated the DNS zones to allow my secondary DNS server to be the Azure VM (by giving it’s Public IP address). So at this point, one name server was my existing on-prem system and the other one was the new Ubuntu VM. The way the DNS lookup system worked, all I would need to do to fail over or fail back in future would be to turn off DNS services on one of these systems!
To test, I turned off the DNS services on my on-prem system that had so far been the DNS server for these zones. Using an Internet based website (big fan of www.dnsstuff.com), tested that the new records were being shown up. Now I went ahead and turned off the local web servers and databases. From here on, if I saw my site coming up (live) anywhere, it would be from the new VM.
This time, going to www.pingdom.com and using their “Website Speedtest Tool”, I tried to load one site after another and checked the headers. Hoorah! The fail-over was now almost complete!
On pingdom, you can see the headers sent by your servers by clicking the little arrow drop down on the far right of every page/resource retrieved for your request.
Step 5 – Fix WordPress Permalinks
For some reason, WordPress cannot remember or respect the permalink structure rules you set up with simply copying over the files or restoring the databases. If you try to navigate to different pages or posts of such a copied over website, you will get 404s for everything except the homepage. Not sure what’s up with that one! Anyway, this is simple to fix.
From a web browser, navigate to the /wp-admin/options-permalink.php of every website and simply click the “Save Changes” button. Now all the pages and posts will show up correctly.
With that, the fail-over is complete!