«    »

Running WordPress 2.0 under IIS

WordPress is the blogging / content management software I use to run this site. WordPress was designed to run under the Apache web server. However, the hosting company for my website uses Microsoft's IIS web server to serve most content, including PHP files which WordPress uses. Setting up WordPress to work under IIS was non-trivial, particularly since existing instructions on the web were for version 1.5, while I wanted to run the recently released version 2.0. So I thought it would be helpful to describe the steps I took.

All examples use my website, in which I have WordPress running under a subdirectory of the domain (www.basilv.com/psd) instead of directly under the root. So WordPress itself is installed in directory /psd under my root website directory. Take this into account when using my examples.

First, a little about how WordPress works. WordPress serves all normal content via the index.php file. Given a URL such as http://www.basilv.com/psd/index.php/blog/category/miscellaneous/, the WordPress code called by index.php parses out the path after index.php (/blog/category/miscellaneous) and displays the content associated with that path.

The first problem running under IIS is that the above URL is interpreted to be pointing to a directory - index.php is considered a directory instead of a PHP file to be invoked. To change this behavior, a php.ini file must be created and placed in the website root directory with the following contents:

cgi.fix_pathinfo = 1
cgi.force_redirect = 0

The second problem I encountered is that the .htaccess file provided by WordPress is considered invalid by IIS - it serves a HTTP ERROR 500 whenver trying to access anything in a directory containing an invalid .htaccess file. The solution is simply to delete the file.

WordPress may somewhat work at this point, but with 'ugly' URLs containing index.php in the middle. I wanted clean URLs, so had configured WordPress to use nice permalinks. My permalink structure is /blog/%year%/%postname%. The .htaccess file provided by WordPress uses the Apache mod_rewrite module to convert (rewrite) 'clean' URLs to include 'index.php'. (By the way, this is a big improvement over WordPress 1.5, which required quite a complex .htaccess file which WordPress had to update every time a page was added.)

To use clean URLs, we therefore need URL rewriting capabilities in IIS. The solution is to have the ISAPI_rewrite module installed on the IIS server. With this module running, a httpd.ini file can be added to the root website directory (not under /psd, where the .htaccess was located) with the rewrite instructions.

Unfortunately, the ISAPI_rewrite module is not 100% compatible with the Apache rewrite module, and in particular is missing some (many?) of the capabilities found in the Apache module. Therefore, the conversion from .htaccess to httpd.ini is non-trivial. Let's look at the .htaccess file found in the /psd directory:

RewriteEngine On
RewriteBase /psd/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /psd/index.php

The main lines are the two lines starting with RewriteCond plus the RewriteRule line. What these 3 lines are saying is that for any URL that is not a file (!-f) or a directory (!-d), replace the first character of the URL with /psd/index.php. In conjunction with the RewriteBase line, this essentially converts a URL of the form www.basilv.com/psd/foo/bar to www.basilv.com/psd/index.php/foo/bar.

Directly converting this to ISAPI_rewrite is not possible, because ISAPI_rewrite's RewriteCond directive doesn't support the is-a-file (-f) or is-a-directory (-d) tests, and the RewriteBase directive isn't supported at all. So I wrote rules to convert all URLs starting with /psd to add in the index.php:

RewriteRule ^/psd/$ /psd/index.php [L]
RewriteRule /psd/(.*) /psd/index.php/$1 [L]

This worked, partially. The problem is that images and style sheets associated with the theme were not being loaded, because their URLs were also having the index.php added. I also had some images and files outside of wordpress, but under the /psd directory, that were also incorrectly being rewritten. So I had to add rules for each of these cases before the above rules to map such URLs to themselves and then terminate (the last rule option [L]) before reaching the above rules to add in 'index.php'. Essentially, this is a manual implementation of the RewriteCond rules used in .htaccess to ensure that files & directories do not have their URL mapped. The relevant portion of my final httpd.ini file is:

[ISAPI_Rewrite]

# Rules to ensure that normal content gets through 
RewriteRule /psd/software-files/(.*) /psd/software-files/$1 [L]
RewriteRule /psd/images/(.*) /psd/images/$1 [L]
RewriteRule /psd/favicon.ico /psd/favicon.ico [L]

# For file-based wordpress content (i.e. theme), admin, etc.
RewriteRule /psd/wp-(.*) /psd/wp-$1 [L]

# For normal wordpress content, via index.php
RewriteRule ^/psd/$ /psd/index.php [L]
RewriteRule /psd/(.*) /psd/index.php/$1 [L]

When working on the rewrite rules in the httpd.ini file, I ran into problems testing due to the browser cache. I was getting inconsistent / unexpected results due to the browser caching prior results. The solution is to clear the browser cache, which in Firefox can be done via the menu item Tools | Clear Private Data.

Another issue is having WordPress send emails (i.e. when a comment is waiting for moderation). The default approach used by WordPress doesn't appear to work under Windows. The solution I found is to install the wpPHPMailer plugin which allows you to configure WordPress to use any SMTP server to send the emails.

One issue I was unable to resolve is a problem with the post preview feature. Under IIS, post preview doesn't work (due to a 404 error) when the article is in draft status. The workaround is to change the status to private if you want to preview your post. This problem is due to a defect in WordPress that is fixed in WordPress 2.0.1.

To summarize the steps to get WordPress 2.0 working under IIS:

  1. Add php.ini file to correctly resolve URLs containing index.php.
  2. Remove .htaccess file which IIS can't handle.
  3. Install ISAPI_rewrite module on IIS server to provide URL rewriting capabilities.
  4. Provide httpd.ini file to rewrite URLs.
  5. Install and configure wpPHPMailer plugin for sending emails.

If you find this article helpful, please make a donation.

55 Comments on “Running WordPress 2.0 under IIS”

  1. @Christoffer, thanks for the tip. It will only work if you have the authority to install an ISAPI filter under IIS, which is not always the case (i.e. if your ISP manages the server).

  2. Vas Lor !!! says:

    thanks a lot !!!!!!

  3. [...] To remove the index.php, then one can either use the custom 404 redirects or isapi_rewrite. [...]

  4. [...] Professional Software Development » Running WordPress 2.0 under IIS [...]

  5. Frank says:

    I found the article helpful for setting up a httpd.ini on dotster hosting site. Sorry about the donation (none) since I am out of work still.

    This was my final result which seems to work so far:

    [ISAPI_Rewrite]
    # For file-based wordpress content (i.e. theme), admin, etc.
    RewriteRule /wp1/wp-(.*) /wp1/wp-$1 [L]

    # For normal wordpress content, via index.php
    RewriteRule ^/wp1/$ /wp1/index.php [L]
    RewriteRule /wp1/(.*) /wp1/index.php/$1 [L]

    # Be sure to put this rule at the bottom
    RewriteRule /wp1/(.*)$ /wp1/index.php/$1 [I,L]

«    »