I've spent the morning experimenting with cloning my Ubuntu LAMP server. My existing server is a virtual server setup with virsh. Both host and guest are Ubuntu server 11.04. The host is setup with nothing but the requirements to run virtual servers and control it via ssh so I don't have to leave the monitor connected. The guest is a LAMP server running a couple of Drupal sites. The server I'm setting up now is running on a Windows 7 x64 host through virtual box. I'm testing this so that in the event of a hardware failure of my host server I have a backup server ready to go. I'm only experimenting here so most things are done manually so I'll get around to automating the process later
The first step of course was to setup a new LAMP server. This the easiest part of the process. I've setup a VM in virtual box with a 40GB HDD. I've allocated 1 CPU and 512mb of RAM. This is a modest setup but I don't have anything demanding on the server and I can always increase this if necessary. The most significant change I made was to change the network settings from "NAT" to "Bridged adapter" This allows the Guest to access the network directly.
Ubuntu 11.10 is out now but I'm using 11.04 since my old web server runs on this. When I've got a backup in place I'll test the new version. The install is fairly straightforward. When asked what setup I wanted I selected LAMP server and SSH server. For the purposes of this test I don't really need the SSH since I'm sitting at the PC anyway but I thought it prudent incase I actually need to use this backup for a while. You will be asked to specify a MySQL root user password
The first thing I did when the system was setup was to define a static IP address.
To do this you need to edit the file "/etc/network/interfaces" I used nano so my command was
sudo nano /etc/network/interfaces
The important section is the primary network interfaces.
You need to change this
#The primary network interface
iface eth0 inet dhcp
#The primary network interface
iface eth0 inet static
"address" needs to be the IP address you want to assign to this server. You will need to restart networking on the server after doing this. "sudo /etc/init.d/networking restart"
I use phpmyadmin to manage my SQL databases so my next step was to install it on the backup server "sudo apt-get install phpmyadmin". Setup will ask you for a root password to access phpmyadmin and the MySQL root user password.
Next I copied my Apache site files from my source server. To do this I used fireftp to access the server via ftp. I copied everything in my /etc/Apache2/sites-available directory onto my desktop PC and then (via ftp again) onto the backup server. To do this you will need to change the permissions on the backup server "sudo chmod 777 /etc/Apache2/sites-available" and then back again when your done "sudo chmod 755 /etc/Apache2/sites-available".
Next I had to copy all the website files. On this server they are stored in /var/www/sitename. I have several sites and theres thousands of files so I thought it best to archive them and compress them. Uncompressed they are around 500MB. Compressed they are 150MB.
To compress the files on the source server
tar -cjf www.tbz /var/www
You can also use -v to get the output of the files being processed but I'd rather not, I'm not going to read the output. www.tbz is the filename of the archive, which I'll be moving to my backup server. /var/www is the folder I'm archiving. All the subdirectories are included of course. I downloaded the www.tbz and then uploaded it to my backup server. To decompress it by default it decompresses to the directory the file is in so it may be easier to put it in your root directory. I put it in /var/www and when decompressing I got /var/www/var/www. When defining the decompress target as /var/www I still got /var/www/var/www so I defined the target as /
sudo tar -C / -xf www.tbz
You will need to create the directory your decompressing to first if it does not exist since tar does not seem to create one.
Ok so now my files are there I can enable my Apache sites. On the backup server type "sudo a2ensite *" This will enable all sites. If you only want some of them enabling you'll have to do it one by one. The reason we do this after copying the files over is so we don't get any error messages from Apache that the target folders do not exist. If you're using clean URLs, like I am (and you should be) then now would be a good time to enable Apaches rewrite engine "sudo a2enmod rewrite". You will be prompted to restart Apache so do so. I forgot to do this on my first run and didn't spot it at first since the front page opens OK. I spotted it when I tried to login to update this post. I want given any error messages, it just wouldn't login.
Lastly we need to copy all our databases and the database users. I'd done this by setting up database replication with my backup server as a slave. This will save me a step next time I take a backup since all I'll need to do is leave the backup server on and it should sync the databases. To do this you need to login to phpmyadmin on both servers. In separate browser tabs/windows.
You'll need to login with root access to both servers. On the backup server go to the replication tab. The backup server will be our slave server. Theres an option to configure master and another to configure slave. When configuring slave we need to tell it the IP address of the master server and give it login details. The root login details will do for now. You will also notice it gives you a server ID. You need to take this and add it you you /etc/MySQL/my.cnf file. anywhere under the [mysqld] section should be fine. I don't know if the order of settings is important here but I used one that was already there. If you read through you will find "#server-id =1" If you remove the # and change the 1 to the number phpmyadmin gave you that should do. You could also add "report-host=hostname" if you want your master server to report when the slave is connected. Save the file and then restart MySQL "/etc/init.d/MySQL restart". Then save the settings on phpmyadmin. After saving the settings I got an error message that the SQL thread and IO thread were not running. Click on "Synchronize database with master" and then on go. It will take quite a while to run depending on the size of the database and connection speed. When mine finished it simply stopped loading. I still had the error messages about the SQL and IO threads not being started. The database list in the left column now had only one entry. I clicked on the replication tab again to refresh the page and the database list populated correctly but I still had the error messages. I had to click on control slave and then on Full Start. It took about 30 seconds for the IO thread to start. I kept clicking on the replication tab to refresh the page until it started.
You will notice that the users are missing. They are stored in the "MySQL" database but this is skipped in the sync process. You can add your users in manually but if you have a lot this can be tedious. Especially if you have a lot of permissions to set. Thankfully this can still be semi automated. The method I'm using to automate it breaks the replication process and I haven't found a fix for that yet. At the moment that's not a problem for me but I'd encourage you to create the users manually if you can. On the slave server click on the synchronize tab. You will be asked to select a source and destination database. On the source type the hosts IP address and enter the root username and password. In the database box type "MySQL". On the target database select "Current server" and then select the MySQL database. When you click go you will be shown differences in the databases and asked which parts you want to sync. I selected them all and then clicked on "apply selected changes".
It might be a good idea to test the new server. In my router I have several ports forwarded to the IP address of my web server. I just need to change this IP to the IP address of the backup server and test the webpages on the new server. Assuming all goes well I can now experiment with my old server while the new one runs my sites.
As I said earlier I will eventually get around to scripting this. I'd ideally set something up to start the backup server in the event the main one fails. Currently I'll have to do this manually. Currently though I can now script most of what I've just done and schedule it to do a regular backup. The more observant amongst you will notice that phpmyadmin shows you the script it uses at the top of the page. Now I've got my backup server though its about time I made some changes to my main server. Watch this space....