Blog by Edo Frederix edofrederix@gmail.com RSS

Running vBulletin on mutiple servers

July 28, 2011

Abstract

vBulletin has some pretty sound multi server support. Sessions are for example centrally stored in MySQL. But what if we're running Lighttpd on port 81 with Nginx frontend and having clean URLs?

First we have to make sure that the backend webserver detects the right ip for a user. This ip is important for distinguishing different users from each other. In includes/class_core.php, we need to replace all two instances of $_SERVER['REMOTE_ADDR'] with $_SERVER['HTTP_X_FORWARDED_FOR'], or whatever header rewrite your frontend webserver does to inform the backend webserver about the proper ip address.

Also, if the backend is not running on port 80 or 443, vBulletin will automatically append something like :portnum to the domain name. This then will mess up the request, because the client will now try to access this different port on the front end. To solve this, we need to force vBulletin to always use port 80. Around line 2041 in includes/class_core.php we change the code into:

// Get server port
$port = 80;
$port = in_array($port, array(80, 443)) ? '' : ':' . $port;

If we want to use pretty SEO URLs in vBulletin, then we need some server sided URL rewriting. vBulletin by default comes the appropriate .htaccess and web.config rewrite files. Nothing for Lighttpd though. I came up with the following rewrite scheme for Lighttpd. So far it has been working well.

url.rewrite-once = (
  "/threads/([0-9]+)(?:/?$|(?:-[^/?]+)|(?=?p=))(?:/?$|(?:/page([0-9]+)?)|(?:?((?:&?[a-zA-Z]+=[^/?&#]+)*)))" => "/showthread.php?t=$1&page=$2&$3",
  "/members/([0-9]+)-[^?]+(?:[?](.*))?" => "/member.php?u=$1&$2",
  "/forums/([0-9]+)(?:[^/?]+)(?:[/]page([0-9]+))?(?:?(.*))?" => "/forumdisplay.php?f=$1&page=$2&$3"
)

If I'm correct, since 4.1.5 there's some enforced canonical URL checking present in the code. With the lighttpd rewrite scheme given, this leads to bad repetitive 302 redirects, resulting in a browser crash or error. This is not something we want, so I have disabled the canonical URL enforcement.

It's a good idea to force your clients to only use a single domain. This creates consistency for your cookies and URLs. For example, redirect domain.com to www.domain.com in nginx with:

server {
        listen          80;
        server_name     domain.com;
        access_log      off;
        rewrite ^(.*) http://www.domain.com$1 permanent;
}

Then you can make a new server{} block for the www.domain.com, with your server settings.