This article examines why a local development and testing environment is a good idea for a remotely hosted WordPress site, and how to go about installing such an environment with the open source XAMPP web server stack on a Windows PC.
It’s good practice, based on professional development methods.
In well-funded private sector environments staffed by skillful specialists, every live system has at least one development environment, but maybe several sandboxes independent of each other.
Each of these sandboxes connects to an n-Tier development environment of servers and software. The concept of ‘n-Tier’ architectures refers to the number (hence the n) or levels of components in a complete system. The reason I specified well-funded above is that the expense of a system increases with every layer of hardware and software required.
For that reason, the development environment might not resemble the production environment very closely at all, as suggested in the hypothetical model illustrated in Figure 1 below. In that hypothetical, a bunch of developer PCs or laptops connect to just two development servers simulating a production environment that involves five servers (and maybe even more if one or another function is clustered for failover or scalability).
The products of development are eventually deployed into a staging environment that, as a matter of best practice, should mirror the production environment as closely as possible, from precisely corresponding versions of operating systems, patches, middleware, and right down to hardware specifications for CPU and RAM.
A staging environment can be used as an administrative and user acceptance testing ground, though these functions are sometimes further separated out.
Only when the latest version of an application or its components passes testing is it rolled out to the production environment, live to its intended user groups.
Why do professionals go to such expensive lengths to develop and test separate from live environments? Because long-term experience shows that even the best, most well intentioned plans can contain serious or even disastrous flaws that no one spots until the system is live and under load.
But why should that concern the owners or users of WordPress blogs? Only you can answer that question for yourself. However, imagine you operate a WordPress site and one evening you make what you thought were minor changes, but minutes later the entire site collapses. Later your hosting provider tells you that the last backup failed and the best you can hope for is to roll back to a version that is days, weeks, or even months older than the last changes – which are now lost to you. If that idea bothers you, it’s reason enough to set up and maintain a local development environment.
With XAMPP, anyone with a half-decent PC/laptop can combine all the separate functions shown in Figure 1 above as developer PCs, development servers, and staging environment into a single environment on a single computer. This development and staging environment eliminates the uncertainties of moving various components from mismatched servers into entirely new configurations, as shown in Figure 1 between the development and staging environments.
Virtualisation of WordPress enabled services at the web hosting end eliminate the need for the WordPress developer to consider production architectures, which can remain completely opaque so long as PHP and MySQL/MariaDB are supported appropriately. This is part of the appeal of WordPress and XAMPP: they have a wide enough user base to have spawned ubiquitous support.
Before moving on to the ‘what’ and ‘how’, there are some assumptions that need to be clearly stated.
This article focuses solely on Windows environments, and specifically Windows 7 SP1 or later.
It is assumed readers know how to administer their own operating systems, and how to use common tools like compression packages (zip, tar, etc), and FTP/SFTP/SSH programs to download/upload files between local and remote destinations.
It is also assumed that readers use text editors, not word processors, to fiddle with code and database files, but because this is such a critical failing in so many cases I have observed, let me stress that the reason for using text editors is to preserve non-formatted character sets, and the importance of doing that is critical: a single comma, formatted the wrong way, can invalidate an entire database, or thousands of lines of code.
There will be no focus here on WordPress versioning or coding issues, and very limited focus on MySQL query syntax. Those are important facets of working with WordPress, but are marginal to the topic of this article. Information on every aspect of these, and most other related topics, is readily available elsewhere online.
All the programs necessary to accomplish the tasks described here are freely available online, as is a wealth of advice on how to use them.
Before going on, I strongly recommend that if you are using this article as the basis of installing a XAMPP development environment, do nothing until you have finished the article. At the very least be aware that XAMPP ought to be installed and tested before WordPress is added to the mix.
First, let’s be clear about WordPress. This article deals with the stand-alone open source package (www.wordpress.org), not the online hosted version (www.wordpress.com). The major difference is that the standalone package is fully customisable and can be hosted anywhere.
Often referred to as a blogging system, mainly because that’s what most people use it for, WordPress is actually far more sophisticated, and represents a significantly featured content management system (in the same vein as Drupal, Microsoft Sharepoint, or properly configured Wikis).
WordPress is based on the server-side programming language PHP, which originally stood for ‘Personal Home Page’, but is now referred to as ‘PHP Hypertext Preprocessor’.
Server-side means that functions are executed on the web server, not the client machine. That means PHP requires a web server to recognise and execute its functions. More on web servers shortly.
The WordPress PHP code is contained in the installation package of PHP ‘pages’ that make up the WordPress administrative and user interface, as well as the templates that create the look and feel of WordPress sites.
The PHP code requires a back-end database, MySQL or Maria DB (the latter being identical in administrative and functional respects, but with added extras for advanced users), to store configurable information and the site content composed of words. MySQL is a fully-featured open source relational database management system (RDBMS) that comes with its own graphical user interface, Workbench, but can be adequately administered with tools offered by XAMPP.
The database stores only configuration information and text-based content; images are maintained separately in a folder under the WordPress directory structure:
%WordPress% is the root directory of the WordPress installation. Images are fetched from that directory by information retrieved from the database which links them to the appropriate content and code. My point is that the database is as critical to WordPress as the PHP and web server.
WordPress currently does not support any database other than MySQL, though experienced programmers have the ability to change the code to address and query more powerful databases like Microsoft SQL or Oracle.
To run PHP, the preferred web server is the open source Apache, the most widely used web server software in the world, with a reputation for robust reliability second to none.
This is where XAMPP comes into the picture.
XAMPP for Windows
People who know how to set up and run a web server without a graphical user interface (GUI) don’t really need XAMPP. Nor do people who can make the diabolical Microsoft IIS web server work without running into all sorts of user permission and firewall issues. The rest of the world might prefer a smaller, standalone, but comprehensive package like XAMPP, which is an acronym for parts of its components: X standing for cross-platform (Linux, Mac, Windows); A for Apache HTTP Server; M for MySQL; P for PHP; and another P for Perl (which is another programming language).
However, the latest release of XAMPP also includes OpenSSL security management; the phpMyAdmin GUI that can be (and is recommended to be) used to configure both PHP and MySQL in a XAMPP installation; the open source FileZilla FTP server; the Mercury email server; and the Apache Java web server, Tomcat.
The minimum required components for a local WordPress development environment are PHP and MySQL. However, the XAMPP installation has a relatively light footprint, so a full install is recommended here in case other components are required down the track. Re-installations or top-ups can be messy.
To download and install, navigate to https://www.apachefriends.org/index.html and read the instructions.
The only advice about installation offered here is to carefully consider from where XAMPP should run. For example, if you intend to establish your development environment inside the XAMPP directory structure, as is often recommended, you should consider carefully how this might conflict with the obstructive mess Microsoft has made of user and group permissions; even when logged in as an administrator, user processes are frequently locked out of programme directories, and prevented from editing configurable files.
My advice: install both XAMPP and WordPress outside the Microsoft operating system and programme directory structure. You might, for example, consider running your development environment in a folder under c:, called WP, or WPdev, or whatever makes sense to you, particularly in relation to the name you will pick for the virtual server running on your system.
When considering XAMPP’s installation options I strongly recommend not to install its components as ‘services’ unless you know exactly what a Windows service is and why you need one for each XAMPP component.
Those components are completely unprotected by default to make installing XAMPP simple. But this also means that if users do not pursue minimum security procedures after an installation, any half-competent hacker can access Apache or PHP running through XAMPP by using default ports and username/password pairs to access their functionality. That functionality permits a skilled user to take complete control of a host system.
This security consideration implies two things I am not going to detail in this article: all default usernames and passwords for XAMPP and its components should be changed immediately after installation, and none of the components should be left running in the background when they are not in use for configuration or development purposes.
After installing XAMPP, and playing around with it for a little while, if that’s what you like to do, install WordPress.
The WordPress installation package can be downloaded from https://en-au.wordpress.org/. The same rules apply: read the installation instructions, follow the prompts, and pay attention to where you are installing the package.
Do not configure any part of WordPress after installation. You just want the virgin install at this stage.
This is all pre-preparation. Now comes the hard part. The how.
After XAMPP has been correctly installed, and with both Apache and MySQL running to ensure that they can be started (see Figure 2: XAMPP control panel), your Windows system will recognise XAMPP’s http interface as a website running from your local loopback address –
It should look similar to Figure 2, where arrow ‘a’ points at the XAMPP URL, and arrow ‘b’ points at an invitation to install WordPress from third-party provider BitNami, which I do not recommend.
Why not? As a third party, BitNami has an agenda unlikely to be disclosed amid the gushing marketing copy about how easy it is to use. At best, however, using a third party as an intermediary for doing what you could do on your own means potential private data harvesting or theft. At worst the promised ‘ease of use’ will never materialize as Windows’ inbuilt security features prevent any automation of the server configuration tasks described below, leaving you with an aborted, messy half-installation.
Unless you have significant reason to trust BitNami, configure your environment yourself!
Configuring local virtual hosts
The 127.0.0.1 loopback address always refers to local hardware and software, and to run a development environment on a local machine (your desktop/laptop) you need to ‘tell it’ that the same address should link to the relevant development site(s) as well as the XAMPP interface already using it.
You do this by sharing the single 127.0.0.1 address with aliases, or virtual host names. You can set up as many virtual hosts as your machine can support with hardware resources (RAM, CPU, hard disk space).
Virtual hosts are configured in both Apache and the Windows ‘hosts’ file. The latter can be found in:
The hosts file has no file extension.
Before moving on, it is a good time to mention that making backup copies of everything you change, particularly when you don’t know exactly why and how you are changing things, is not just common sense, but part of professional IT best practices. I recommend making backups of every file you alter by copy-pasting it into the same directory as the original, and including a date in the backup filename (ie, ‘hosts’ to ‘backup-hosts-23-11-2014’). Precise naming conventions are less important than quickly recognisable clues about when the backup was made, allowing decisions down the track about deleting such backups after everything proves to be working well.
I also recommend annotating any file you change to leave a note behind reminding you,m or someone else who may need to use the same file, what the changes do, and why they were made. Commenting conventions are different for different files; look them up if and when you need to, but don’t just type words without making sure they are rendered neutral by the special symbols for annotation. Commenting examples –
# for hosts,
## for .conf files – are included in the snippets below.
You may have to grant read/write access to see and alter the hosts file. Make the backup, then edit the original, or create a copy, edit it as shown below, then delete the original and rename your copy to ‘hosts’.
In the hosts file you should add these two entries if they don’t already exist:
127.0.0.1 localhost #added for XAMPP dev environment 127.0.0.1 <the name of your development virtual server, ie: WPdev, or WPdev.com> #virtual host added for WP dev
The word in between the angle brackets will be the hostname. Do not include the angle brackets in the name (ie, they are shown here only to tell you what to customise). After saving the
hosts file, you now need to make changes to the Apache virtual hosts configuration file, the
httpd-vhosts.conf, which can be found in:
In that file you must have entries to validate both the XAMPP configuration console files (the files that show XAMPP’s admin screens) and your development virtual host(s) against the single loopback address.
So, add the following at the end of the
httpd-vhosts.conf file if the entries don’t already exist:
##vhosts added for XAMPP WP dev environment NameVirtualHost * <VirtualHost *> DocumentRoot "C:xampphtdocs" ServerName localhost </VirtualHost> <VirtualHost *> DocumentRoot "C:[the directory of your WordPress content files]" ServerName [WPdev, or whatever virtual host name you picked] <Directory "C:[the directory of your WordPress content files without a trailing slash]"> AllowOverride All Order Allow,Deny Allow from all Require all granted </Directory> </VirtualHost> ##end of XAMPP virtuals list
Replace the contents between, and including, the square brackets with the hostname and full directory path to your development site, and make sure the server name is the same you used in the Windows hosts file.
The override statements that follow might seem like overkill for granting access to the directory, but I had a hellish time convincing Apache to let me access my own development server when I first did this; the illustrated combination of privileges finally worked for me.
You can create multiple virtual servers by adding similar entries to both the
Restart Apache and make sure that when you navigate to
http://127.0.0.1/ you still get XAMPP’s welcome screen.
Export your blog database
For the purposes of this article I’m assuming you already have a live WordPress installation. If that is not the case, the instructions that follow may become useful only down the track, as you get closer to uploading your newly created WordPress installation to a public web hosting infrastructure.
So, if you already have a live WordPress site, your web hosting company should have some kind of GUI interface for your remote virtual server that will permit locating your database and exporting it to a folder in your website, from where you can download it to your local machine.
If you are unsure about the database name, open up the file
wp-config.php with a text editor. This file should be in the root directory of your WordPress installation. It has a line in it that specifies:
Whatever is mentioned instead of ‘WP_db’ is the name of your database.
Downloading this file shouldn’t take too long. My database is already pretty large at more than 40Mb, but it was exported to the remote server, and downloaded to my local machine in about 20 minutes across a slow ADSL link. Note that you may be given options on what to name the exported file; give it the file extension .sql to make it more simple to import later.
I am not going into the details of FTP usage, but I do not recommend using the XAMPP FileZilla server rather than a client, and I strongly recommend using the ssh/sftp protocol father than open ftp, not just because it’s more secure, but also because it tends to avoid firewall problems with the ridiculously large number of ports that have to be opened, and probably left open, to make standard FTP work reliably.
Massaging the database
You will need to edit your database file to change all the references to the live server, altering them to use the local virtual server name instead. So, for example, all references to
http://mysite.com/ should be replaced with
http://WPdev/ (or whatever name you picked for the virtual server).
In my case it takes about 1 second to make several thousand replacements in my database file. When the appropriate changes have been made, save and close the database file.
Create a local database and import the data file
Access the XAMPP myPHPAdmin console, either by clicking the admin button for MySQL in the XAMPP Control Panel (see Figure 3, below), or by clicking the link in the orange left-hand menu bar of the XAMPP http interface.
Log in with administrator credentials. Make sure you are logged into 127.0.0.1 or the virtual hostname you specified. The top of the administration window will tell you where you are.
Now create a new database of the same name as your live one. This will be an empty database with a name only.
Once that’s done, import your downloaded and edited database file into the empty new one.
Depending on the size of your blog, this could take long enough for a cup of tea.
Download WordPress files
This is not to be confused with installing WordPress on your local machine. Instead it is the process of downloading all the WordPress files already running live on your remote server so they can be used locally.
In my case I simply zipped up and downloaded my active remote WordPress theme, extracted it into a directory that matched the directory structure of my local virtual host with my live one.
Remember: all media files in your blog are saved into a separate directory:
%WordPress%wp-contentuploads. You will need to download that entire directory to the same path on your development server if you wish to see your pages in the development environment as they appear live.
When all this is done, stop and restart Apache and MySQL from the XAMPP control panel, and use your favourite browser to navigate to
http://WPdev, or whatever you called your virtual host;. Aapache and MySQL should be restarted any time a change has been made that might require initialisation at startup, which mostly means every change to how they run.
If everything worked you will see the first, or homepage, of your WordPress installation. Just make sure the browser is pointing at the local site, not the remote one (which may have been cached as a default correction for your typing).
If there is an access denied message, something went wrong with the permissions in the httpd-vhosts file: troubleshoot there. Also ensure that Windows has not denied access to the directory into which you installed your virtual server.
If there is an error message about missing content, something went wrong with the database export/import process. Do it again extra carefully.
If you get the XAMPP control pages for PHPMyAdmin instead of your blog, something went wrong in either the hosts file or the http-vhosts file, or both. Make sure 127.0.0.1 is forwarded to both localhost AND your virtual host name. Also make sure the virtual host name is identical in both files.
If nothing seems to work, go right back to the beginning, paying extra close attention to configuration details and error messages. Google every aspect of the process you don’t understand until you find the information to give you the necessary insights.
One of the biggest benefits of both WordPress and XAMPP is that they have a huge user-base of bloggers and forum members who are likely to have encountered every variation of problem possible, and written about potential solutions.
The development environment should not really be used for preparing ordinary posts – it is a development environment, implying major configuration changes.
WordPress is best used live for ordinary posts and minor changes. But the development environment is great place for your own backups. Perhaps you can run a weekly cron job to export your WordPress database so you can download, massage, and import it into your development environment.
Just remember that any major changes each way require database exports and massaging. This would be tedious as a daily ritual.
I use the procedures detailed here only for changes like migrating from one theme to another, or adding an entirely new section of content (more than half a dozen posts).
Best of luck with your WordPressing.