Running WordPress on IIS

So, you want to run WordPress on IIS? There are a load of posts out there which advise against it with all sorts of reasons. Some of the actual problems I have encountered, and everyone else seems to encounter, and I have since fixed are:

  • Speed – Everyone seems to think PHP runs slow on IIS. The latest versions of PHP and IIS have made significant progress in this area, and set up correctly (ie with WinCache and FastCGI) this isn’t an issue.
  • Automatic updates do not work –  You need to set the permissions correctly
  • Image Uploads fail – You need to set the permissions correctly
  • I can’t update WordPress/Plugins – When running WinCache 1.1 there is a bug which locks files/folders after WordPress has deleted them. This is fixed in WinCache 1.3
  • Pretty Permalinks don’t work – Set up your URL rewrite rules correctly
  • Sending emails does not work – To use some plugins such as Contact Form 7 you need to tweak the php.ini settings to allow emails to be sent.

In this article, I’ll cover off some of the common problems encountered when running WordPress on IIS, which will ensure you get a fully functional and speedy WordPress installation up and running in no time. I am using a clean build of Windows Server 2012, which has IIS 8 already installed. I am using Windows Azure to host my Server 2012 instance. You can also get a 90 day free trial as well.

I am going to use the Web Platform Installer from Microsoft, simply as it does 95% of the setup for for up, and it is now baked into the IIS Management Console in IIS 8. The only problem with it (as of now, October 2012) is that it will install PHP 5.3 (which won’t give you optimal performance) and WinCache 1.1 (which has a bug that prevents you installing updates to plugins). But, once it is all done, it’s very easy to update those two components.

Install and run the Web Platform Installer. In IIS 8 this can be done straight from the IIS Management Console, select the website, and select ‘Get new Web Platform Components‘ from the Actions menu on the right:

IIS 8 Console - Web Platform Installer

IIS 8 Console – Web Platform Installer

If you have not already installed the WPI, it will take you to the download page to run. Once its loaded, you will be presented with the menu. Put ‘WordPress’ into the search box, and then click ‘Add’ next to WordPress, then Install.

You will be prompted to setup the MySql root account; enter a password for it, review the dependencies required for WordPress (ie PHP 5.3,xx, the URL rewriter package, MySql, Windows Cache (or WinCache) are just some of them), and accept the license terms. It will then download and setup/configure everything required. When prompted, enter in the website details you want to use. For this, I’ll leave them as the defaults:

Web Platform Installer - WordPress Setup

Web Platform Installer – WordPress Setup

WordPress will be setup, and, all going well, you will get the completed setup screen:

Web Platform Installer - WordPress Installed

Web Platform Installer – WordPress Installed

From there you will get the standard WordPress setup screen appear in your browser; enter in a site title, administrator name and password, email address, and then click Install.

At this point (all going well that is!), you will have 98% functional and working WordPress site! (I’ll note here that during this setup the FastCGI option was missing from IIS. A server reboot made it visible. Make sure you can see it, as you will need it soon).

The next few steps will address the issues detailed above.

Install PHP 5.4 and WinCache 1.3

If it’s not already running, fire up the Web Platform Installer again, and search for PHP. This time, we need to add PHP 5.4.0 and Windows Cache Extension 1.3 for PHP 5.4.0.

Web Platform Installer - PHP 5.3 installation

Web Platform Installer – PHP 5.3 installation

 

To verify that PHP 5.4 is installed, create a .php file in the WordPress IIS folder and put <?php phpinfo(); ?> into it, then browse to that file. You should be presented with a page stating you are running PHP 5.4, and if you scroll down to the WinCache section, WinCache 1.3 should be installed also.  Getting WinCache 1.3 running will fix the problems encountered with auto-updating WordPress core and plugins/themes where the it will delete all the contents of the directory, then lock everyone out of it (including admins and system accounts) until a reboot is done. One problem down, now to sort out the rest of them.

Setting correct permissions

Getting a “The uploaded file could not be moved to C:\inetpub\www\website\wp-content\uploads” or similar error? Or even just unable to add new plugins/themes? By default the WordPress installation will create a new app pool user, but the website access will be Anonymous access using the local IUSR account. This should be changed to the Application pool identity. Simply open the ‘Authentication’ section in IIS, and edit the properties of the Anonymous Authentication option to use the App Pool Identity:

Wordpress IIS Application Pool Identity

WordPress IIS Application Pool Identity

Next you will need to grant the AppPool user access to the WordPress folder structure. I am yet to find a well documented configuration setup for this, and as such there are a couple of options you could take.

  • Grant the IIS AppPool\<AppPoolName> user Modify access to the entire WordPress folder – not an ideal solution, but if you are doing core updates then it may be temporarily required. Recommended to not leave this permission on a production site.
  • Grant the IIS AppPool\<AppPoolName> user Modify access to just the wp-content folder. This will allow plugin and theme updates/installs and media updates, but WordPress core updates will fail as it has no write access to the root folder and files. Probably the recommended option, and do the above temporarily when doing core updates.

(For more information around the IIS AppPool user, check out this page on the IIS.Net site)

URL Rewrite Rules for web.config

If you want your permalinks to work properly, you’ll need to set up the URL rewrite rules either in IIS via the UI or add them to the web.config file.  After a bit of playing around, I am using the following on my multisite installation and am yet to run into issues:
<configuration>
  <system.webServer>
  <!-- Required for WordPress URL rewriting -->
    <rewrite>
      <rules>
        <rule name="WordPress Rule 1" stopProcessing="true">
          <match url="^index\.php$" ignoreCase="false"/>
          <action type="None"/>
        </rule>
        <rule name="WordPress Rule 2" stopProcessing="true">
          <match url="^files/(.+)" ignoreCase="false"/>
          <action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false"/>
        </rule>
        <rule name="WordPress Rule 3" stopProcessing="true">
          <match url="^" ignoreCase="false"/>
          <conditions logicalGrouping="MatchAny">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false"/>
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false"/>
          </conditions>
          <action type="None"/>
        </rule>
        <rule name="WordPress Rule 4" stopProcessing="true">
          <match url="." ignoreCase="false"/>
          <action type="Rewrite" url="index.php"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

SMTP Email settings

To get emails working you need a SMTP server to use. If you don’t have one, set it up yourself! But regardless of what option you take, you need to edit the PHP.INI file and uncomment the SMTP settings.
1. Open up the C:\Program Files (x86)\PHP\PHP v5.4\php.ini file and find this section:
[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = localhost
; http://php.net/smtp-port
smtp_port = 25

2. Uncomment the SMTP and smtp_port lines, and add in your SMTP server and port numbers.
3. Restart IIS to activate the changes.

 

That’s it really. Hopefully the Web Platform Installer at some stage makes the above changes as part of the installation process, but until that happens, this will need to be done.

 

Enjoy!

10 thoughts on “Running WordPress on IIS

  1. How do you make your iis work so that, you can use a custom domain such as example.com?
    I cant get it to work. Localhost via web matrix and iis express works fine, however going through iis gives me the following error:
    HTTP Error 500.0 – Internal Server Error
    File monitoring is enabled for a file which could not be found
    Do you have any suggestion?

    • Humm, without knowing the full details, it’s hard to say, but it should be as simple as entering in the URL in the setup wizard (or editing it later in the WP settings menu).

  2. Just wanted to drop you a note, to thank you for the blunt “you need to set the permissions correctly” and “set up your URL rewrite rules correctly” solutions. I love it! 🙂 Where I work, we have to tell this to our customers *a lot*…

    In my opinion, you did leave out some basic and advanced PHP-, IIS- and WinCache configuration (optimization) settings. Also, when using a remote MySQL-server instead of one on localhost, *and* that MySQL-server is configured with an IPv6 address, you run into a nasty PHP/mysqlnd and IPv6 bug. This bug causes a very slow connection with the database and thus a slow WordPress blog.

    But this might be outside the scope of your article, which was nicely done.

    • Thanks for the feedback! Feel free to post the optimization settings if you want. I wanted to keep things as simple as possible (hence using the Web Platform Installer), but additional details are always welcome.

  3. Hi,

    did you manage to get rid of the index.php in the permalinks?

    i’ve installed multisite on a server 2008 R2 with IIS 7.5 and everything works fine when i use a permalink structure of just /%postname%/

    however on my server 2012 standard with IIS 8 it always wants to put index.php/%postname%/ and it is driving me crazy! i can’t seem to figure it out

    I have even copied out the web.config file from my iis7.5 to iis8 but it still puts that index.php in… i have no idea how to get rid 🙁

    wondering if you have had the same issue

    • Yes – this site is running on Server 2012. You need to set it to a custom structure in the WP config (Settings, Permalinks, Custom Structure – mine is set to /%year%/%monthnum%/%day%/%postname%/), and then ensure the URL re-write rules are set up correctly. The ones in this post should work fine.

    • @adam: WordPress doesn’t recognize IIS 8.0 due to an invalid server version check. I reported it as a bug and it’ll be fixed in WordPress v3.6. See http://core.trac.wordpress.org/ticket/23533 for the bug report (and quick fix in wp-includes/vars.php). This bug might cause the Permalink structure not being updated.

      @AaronM: keeping things as simple as possible is perfect of course. But, if you have some spare time on your hands, experiment with all the fun things you can do with WinCache (and IIS Output Cache).

      One advice: if you run WordPress on IIS and your MySQL database is on a remote server and its hostname is configured with an IPv6 address (yes, 2 times “and”), then you need to disable IPv6 on the IIS server, or wrap your MySQL hostname in a gethostbyname(), for IPv4. Speeds up your connectivity with a second or 2.

  4. @jan

    thanks for this – i’ll have a look and see what v3.6 brings!

    @AaronM

    I even copied your rewrite rules and whilst they worked – wordpress would always insist on putting index.php in my permalink structure. I was using v3.5.1 of wordpress – i have continued my network on my r2 build but will do some more testing on iis8 when wordpress recognise it!

  5. Hi, thanks for the great post.

    Made a site on Azure but it’s under Brandoo WordPress. Running on SQL and IIS. My problem now is that my search box that was working properly on development is currently not functioning after using it on Azure. Do I need to add anything on my web.config? Would really be glad on your input.

    Regards,
    Kevin

Leave a Reply to Kevin Cancel reply