Deploying Lessn More with nginx and try_files

If you are on the lookout for a self hosted URL shortener, you can’t go far wrong with Lessn More.
Lessn More is a fork of the original ‘roll your own’ shortener Lessn by Shaun Inman.

Lessn More includes some analytics on how many clicks a link has had and the referrers. It isn’t as comprehensive as bit.ly or other similar services. But it’s enough for a quick overview.

I’m always weary about hosted services and what would happen if they just shut down, see http://mashable.com/2009/10/04/cli-gs-shut-down/ and http://mashable.com/2009/08/09/trim-shuts-down/.
So Lessn More is great for me.

Deploying with nginx

So when coming to deploying Lessn More, you’ll find a bundled .htaccess file for use on an Apache server. This contains the neccessary rewrite rules to get you up and running.
So how do we get it to play nicely with nginx?
Well you could just use http://winginx.com/htaccess, which is a great little service for converting Apache configs to ngxinx compatilbe configs.
By pasting in the bundled .htaccess content

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) index.php?token=$1 [QSA,L]

It will give you the following to put in to nginx

location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?token=$1 break;
}
}

This is fine if you want to use if statements in the config, personally if I can avoid them, I will. If you are wondering why, read this - http://wiki.nginx.org/IfIsEvil

Using try_files

Your sold on not using if() statements? Good.
Now you’re going to want to know how to use try_files then.
Lets start with a ‘normal’ try_files block:

location / {
index index.html index.htm index.php;
try_files $uri $uri/ $uri.php;
}

All you have to do is give nginx another location to look at if it the file does not exist.
How? With the @ locator. Inside this location you can now define rewrite rules for nginx to work with. Here I’m using @rules:

location / {
index index.html index.htm index.php;
try_files $uri $uri/ $uri.php @rules;
}
location @rules {
rewrite ^/(.*)$ /index.php?token=$1;
}

This is where you can now add your rewrite rules.

How it handles requests

For example a request for /aJsud comes in. The file /aJsud will attempted to be loaded first, then /aJsud/ (including the defined index files), then aJsud.php (being handed off to fast_cgi), lastly — if all of the first three fail to match a file, the request will be handed off to the @rules block.
The server will now apply the rewrite rules and attempt to load any files matching, in this case it will attempt to load (via the fast_cgi) /index.php?token=aJsud

Perfect, now the php script will be called and the short URL redirected to the long URL :)