Nginx config with WordPress multisite on DreamHost

Probably I should post this on the DreamHost wiki BUT I wanted to throw this out that I figured out a solution to an issue I was having on WordPress multisite since migrating to nginx…

The problem

The issue is that, while permalinks were working as expected, images were all broken, particularly when you were on one of the sub-sites. Now, this is an issue that should be easily fixed when there’s a wealth of documentation available. However, this solution on the DreamHost wiki wasn’t working (I saw some mention that things changed for WordPress 3.5 and presumably that method is outdated).

Heading over to the Codex offers a different nginx config, but this doesn’t work with DreamHost. This is actually the one that I saw iterated many times in many different places but I kept running into the issue that the variable $blogid wasn’t found.  It wasn’t until I saw the full guide on WPMU that I started to key into where $blogid was defined and was able to zero in on that particular issue which is here, where you’re actually setting up the main nginx configuration — something that you don’t have access to with DreamHost’s nginx setup.

So, that wasn’t going to work.

Solution

Back to the drawing board, I found this solution which — with some modifications — works for me:

    location / {
        root   /var/www/example.com/wordpress;
        index  index.html index.htm index.php;
        rewrite ^.*/files/(.*)$ /wp-includes/ms-files.php?file=$1 last;
        if (!-e $request_filename) {
            rewrite ^.+/?(/wp-.*) $1 last;
            rewrite ^.+/?(/.*\.php)$ $1 last;
            rewrite ^(.+)$ /index.php?q=$1 last;
        }
    }
 
    location ~* ^.+\.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$
    {
        root /var/www/example.com/wordpress;
        rewrite ^/.*(/wp-.*/.*\.(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$ $1 last;
        rewrite ^.*/files/(.*(html|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js))$ /wp-includes/ms-files.php?file=$1 last;
        expires 30d;
        break;
    }

If you compare what I have above to the original posted solution, you’ll notice that I stripped out the server declaration (unnecessary, these rules are run in addition to the existing server rules and redeclaring them results in an error on DreamHost) and I’ve pulled out the fastcgi parameters which also threw errors when they were included. This solution apparently originally comes from here which also includes some rules for W3 Total Cache, if you’re running that.