Fun with Nginx: Getting WordPress to work in a Sub-Directory

Well that was fun. After a marathon google session and an almost infinite number of reloads of Nginx I got wordpress with pretty permalinks working in an aliased sub-directory on my windows test laptop.

(Clue – almost every post explaining how to do this is incorrect. An exercise for the interested reader is to find the one that worked …)

This is the simplified excerpt from a server{} directive. [The wordpress root is mapped from somewhere else into the /wordpress sub-directory using the alias directive.]

location @wp {
  rewrite ^/wordpress(.*) /wordpress/index.php?$1;

location /wordpress {
    alias "c:/webserver/www/websites/wpnm"; #where wp actually is
    try_files $uri $uri/ @wp;

    #other config stuff here....
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_read_timeout 300s;
        fastcgi_param  SCRIPT_FILENAME $request_filename;

        include fastcgi_params;

The key bit is the try_files directive looking for a real physical file and then when it isn’t found the @wp rewrite directive grabs the pretty permalink and stuffs it into a query string tacked on the index.php. This works with all the permalink variations that wp offers.

If WordPress is simply running in the root directory then this is easy-peasy and the re-write isn’t needed – simply stick /index.php?$args as the last term of try_files instead of @wp. That config can easily be found on line

The best resource I found for getting to grips with Nginx’s config was a tutorial on Linode’s website: This explains how the order of processing of the location directives works; essential knowledge to do anything above a very basic level.

Creating these configs isn’t that easy due to the limited debug tools. It’s not easy to see why things don’t work and the logs don’t help.

The hilariously uninformative error messages from the fastcgi module are typical – almost any config mistake produces a blank page with “No input file specified.”. Niiiice 🙂  Good luck finding out just what the incorrect parameter was 😉

The best debug suggestions I have found are in this blog post: I had a bit of fun since I started with $document_root$fastcgi_script_name as the SCRIPT_FILENAME as the Nginx docs suggest, but that doesn’t work when using aliases.

Of course, that little gem is not well documented…..