Locally mirror your WordPress blog E-mail
Wednesday, 15 July 2009 06:57

One of the things I like to do in my spare time is break software.

Not intentionally, of course. It's just what happens when I start poking and prodding to see what makes something tick. That's not such a problem on my desktop where a complete reinstall can be done in under an hour, but when I break something on this blog, somebody is going to notice.

To minimise the havoc caused by this addiction, I've set up a mirror of my blog on my local desktop machine, which I update every couple of days to the latest backup. Using this technique you can easily try out new things such as minimising bandwidth usage, trying out new themes or testing plugins without risking your blog's stability or annoying your readers. This tutorial will explain how it's done, but you'll need to use some elbow grease to tweak the procedure to suit your own setup.

If you haven't already installed the LAMP stack, then you can check out this post to walk you through the procedure. It'll also explain how to move the document root to a more accessible location in your home folder. I'm going to continue this tutorial assuming that your document root is a folder called www in your home folder.

My hosting provider uses CPanel for account management, so I'm going to have to write this post based on how my system is configured. Yours may be different, so I'll do my best to explain every step so that you can alter the process to suit your needs.

CPanel offers a function to backup the entire site, creating a dated tar file. It also contains a second tar file that is a backup of the contents of the web site's home folder. After creating a backup, I FTP this folder to my local machine and place it in ~/workspace/blog/backups/. It is from here that I extract the archive into /tmp where I can work on it.

Creating the database

If you don't have a wordpress database on your local MySQL server, then you'll need to execute the SQL statement "CREATE DATABASE wordpress", which can be done at the command line by logging into MySQL using the following (replace the db_username and db_password with the actual values). After the MySQL prompt appears, you can execute the SQL statement, press enter, then type "quit;" and enter again to return to the bash prompt.

 mysql --user=db_username --password=db_password

Automating the process

In order to streamline the process, I wrote a bash script called "wp-extract" that automates restoring a backup. It will extract the latest backup file from the backups folder, restore the WordPress database into my local MySQL installation, replace the WordPress folder in Apache's document root with the contents of the backup and finally alter the backup's configuration so it is no longer pointing at the web site's url. The following is the script.

#!/usr/bin/env bash

# URL of the blog
blog_url='blog.burlock.org'

# Path to the folder that contains the backups
backup_path="/home/neilb/workspace/blog/backups/"

# Username and password for your local MySQL database
db_username="db_username"
db_password="db_password"

#=====================================================

# Find the most recent backup file in the backups folder, by modification date
backup_filename=`ls -t $backup_path | awk 'NR<2'`
echo 'Restoring '$backup_filename

# The destination folder that the tar.gz will extract to
tar_path='/tmp/wp/'${backup_filename%.tar.gz}

# The filename to be extracted
backup_filename=$backup_path$backup_filename

# Extract the backup into /tmp/wp
mkdir /tmp/wp
tar -C /tmp/wp -xvf $backup_filename > /dev/null

# Extract homedir.tar into /tmp/wp/
tar -C /tmp/wp -xvf $tar_path/homedir.tar > /dev/null

# Move the blog to the www folder
rm -R ~/www/$blog_url
mv /tmp/wp/public_html/$blog_url ~/www/

# Determine the name of the Wordpress SQL file (should be something like *wordpress*.sql)
sql_path=`ls -t $tar_path/mysql/*wordpress*.sql`

# Import the database
mysql --user=$db_username --password=$db_password wordpress < $sql_path

# Update the database to the new settings
mysql --user=$db_username --password=$db_password wordpress < files/postcreate_db.sql

# Copy the testing config file into the blog home folder
cp -f files/wp-config.php ~/www/$blog_url/wp-config.php

# Replace the main css file with a slightly modified one so that I know that I'm looking at the backup
cp -f files/carrington-blog.css ~/www/$blog_url/wp-content/themes/carrington-blog/css/carrington-blog.css

# And do the same for the wordpress admin pages
cp -f files/colors-fresh.css /home/neilb/www/$blog_url/wp-admin/css/colors-fresh.css

You will need to tweak this script to suit your needs. I won't go into detail on what the script is doing because it's full of self explanatory comments, but I would like to explain the additional files that are referenced by the script.

postcreate_db

The first file is called is called "postcreate_db", and contains a block of SQL statements that will clear out the values in the WordPress database that reference the real blog.

UPDATE wp_options SET option_value = 'http://localhost/blog.burlock.org' WHERE option_name IN ('home', 'siteurl');
UPDATE wp_options SET option_value = '' WHERE option_name = 'admin_email';
UPDATE wp_options SET option_value = '/home/neilb/www/blog.burlock.org/wp-content/uploads' WHERE option_name = 'upload_path';
SELECT option_value AS 'Active plugins prior to resetting' FROM wp_options WHERE option_name = 'active_plugins';
UPDATE wp_options SET option_value = '' WHERE option_name = 'active_plugins';
UPDATE wp_options SET option_value = '' WHERE option_name = 'permalink_structure';
  • Line1 sets the path to the blog to it's new location under localhost. Without this, clicking a link on localhost would take you to your blog on the net.
  • Line 2 erases the admin email address so that no emails are sent by the local blog.
  • Line 3 points the blog to the correct location of the uploads folder.
  • Line 4 and 5 shows then clears the field that contains the plugins that are used on the blog. All plugins are disabled by clearing the "acitve_plugins" row in the wp_options table in case any of them send messages to a 3rd party site.
  • Line 6 disables permalinks so that your blog can still be navigated in it's new location, although it will be referenced by record identifiers, instead of nice URL's. If your local Apache has mod_rewrite enabled, then you can remove line 6 of the script to keep the pretty URL's.

wp-config.php

The second file is a called "wp-config.php", and is merely a copy of the WordPress file located in the root Wordress folder. I've simply edited this file to suit the blog's new home, by changing the defines for the following values:

  • DB_NAME set to "wordpress"
  • DB_USER set to "db_username"
  • DB_PASSWORD set to "db_password"
  • DB_HOST set to "localhost"

colors-fresh.css

The third file, "colors-fresh.css", is a copy of the wordpress theme CSS file located in wp-admin/css/ that is used on the admin pages. I've made a minor modification to it to make the title bar green as a visual reminder that it's the local mirror that I'm looking at. All that happens is that the one on my local web server is overwritten by the copy I have in the files folder.

carrington-blog.css

Finally, the fourth file is "carrington-blog.css", which is simply a copy of the Carrington Theme main CSS file. Like the third file, I've made a minor change to turn part of the window green so there's no mistakes when making changes. You'll need to find the equivalent file for your theme and do the necessary changes yourself.

blog comments powered by Disqus