A few weeks ago I decided to give Windows 8 a try as it was offered free of charge by the University I attend. As I have a very small hard drive (128GB solid state drive), I decided to use the whole drive for the installation, erasing my Linux partition where I had my web development environment setup.
Earlier today I decided to re-setup my local web development environment, this time on my Windows 8 machine, rather than on a separate Linux partition. This is mostly because as I spend more and more time in Windows for school projects, booting to a different OS every time I want to get some work done on personal project had become a huge inconvenience. Not only that, but I also wanted to see how easily this could be done on the Windows platform.
My web development setup consists of the technologies required to run and test web applications written in node.js, php, and MySQL. Besides the system-specific implementation of the aforementioned technologies, my setup also includes some sort of web server that supports an implementation of php, usually nginx as its very lightweight and can easily be used as a reverse proxy for node.js scripts, as well as some sort of front end for MySQL, usually phpMyAdmin, as it goes hand-in-hand with the rest of my setup.
As such, I decided to install WAMP, as it is a very robust package that I have had experience with before, which meets most of the requirements of my setup: it comes with the latest versions of php, MySQL, phpMyAdmin among other tools that simplify managing my web server in Windows.
Though WAMP also comes with Apache, I much rather prefer Nginx as my main the web server as it’s what I use on my production server (which this blog runs on!), and because I could easily reverse proxy node.js scripts to a path on localhost which I could much more easily share to friends or colleagues over LAN or the internet because I would only have to forward one port for Nginx in my firewall/router, rather than a unique port for every node.js script running on my machine.
The next logical step was to setup Nginx to run as a reverse proxy for Apache as well (there would be no point in trying to get Nginx to work smoothly with the WAMP implementation of php and MySQL since they came prepackaged with and pre-configured to work out-of-the-box with Apache).
First, the port Apache listens on needed to be changed so that it wouldn’t conflict with Nginx running on port 80. To do this I edited the main Apache config file (located at something like C:\wamp\bin\apache\apache2.x.x\conf\httpd.conf depending on the WAMP version), namely these two lines: Listen 80 and ServerName localhost:80 (which one could easily locate using find and replace). I simply changed 80 to 3000, though it could’ve been any other valid/available port on my machine.
Next, Nginx needed to be configured to act as a reverse proxy for Apache. I decided to do this by forwarding all requests beginning with a path, namely /wamp/, to Apache. To achieve this I simply added a location directive to the default server directive inside Nginx’s main config file nginx.conf:
location /wamp/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000/;
proxy_redirect off;
}
Now all requests to /wamp/ point to Apache’s root directory and any request to a specific Apache URI can be reached by prepending /wamp/ to it (to access WAMP’s phpMyAdmin you’d go to localhost/wamp/phpmyadmin/, etc).
This seems to work for most things one might use WAMP for, though one notable exception (and kind of a big one) seems to be phpMyAdmin. WAMP now ships with phpMyAdmin 3.4, which relies heavily on Ajax for virtually any communication with the back-end; when accessing phpMyAdmin through Nginx, Ajax requests tend to hang and sometimes the browser window becomes unresponsive. Oddly, the javascript console doesn’t show any errors, so either the request or response seems to be getting lost at some point in the communication. This doesn’t happen if I access phpMyAdmin straight through Apache (via localhost:3000/phpmyadmin/), so I’m thinking it has something to do with the way I setup my Nginx proxy. I haven’t had that much time to look into it, but I’ll update this post if I figure it out.
The good news is that WordPress seems to be working fine with the current configuration, which is great because that’s what most of my client work revolves around.
Update 12/22/2012
So it appears I ran into an issue when accessing WordPress via different hosts: when accessing WordPress directly through Apache (<code>localhost:3000/wordpress/</code>) as opposed to Nginx (<code>localhost/wamp/wordpress/</code>) and then again while accessing it through Nginx over WAN. Part of it was because WordPress uses a “hardcoded” base URL to link to resources as well as redirects, causing issues when accessing the WordPress from a host that didn’t match the one stored in the database. The other issue was due to an Apache redirect when accessing WAMP over WAN because the WAN host differed from the one specified in <code>httpd.conf</code>.
To fix the Apache issue, I simply opened <code>httpd.conf</code> and commented out the line <code>ServerName localhost:3000</code> forcing Apache to try to guess the hostname whenever it has to do redirects and whatnot.
Next, to fix the issue with WordPress’ “hardcoded” base URL, I opened up <code>wp-config.php</code> and added the following code before the “do not edit past this point” warning:
$host = $_SERVER["HTTP_HOST"];
$uri = ($host === $_SERVER["SERVER_NAME"] || $_SERVER["SERVER_NAME"] !== "localhost" ? "/wamp" : "") . "/wordpress";
$base_url = "http://" . $host . $uri;
define('WP_HOME', $base_url);
define('WP_SITEURL', $base_url);
The code above determines the host and uses it to construct the base URL for WordPress dynamically, overwriting the one specified in WordPress’ <code>wp-options</code> table.