April 2008

Moving to Nginx

If you’ve followed me on Twitter, you might have noticed that I have swicthed to Nginx from Apache. Their configuration files are so much simpler than Apache’s and since I don’t use any Apache-only features, the switch went rather painless.

You might have the same need as me, so here’s how I use Nginx:

My setup

It’s pointless to read configuration files without any context, so here is a simple diagram of our network:

 - - - - - - - - - - - - - - - - - - - - -   
|                INTERNET                 |
 - - - - - - - - - - - - - - - - - - - - -   
        ^
        |     81.166.222.185    
________|__________________________________
        |
        v
 - - - - - - - -             - - - - - - - 
|     main      |   <--->   |   judofyr   |
 - - - - - - - -             - - - - - - -
  192.168.1.100              192.168.1.110

Unfornately, we have only one IP-adress, so on our main server we use Apache as a proxy to the other servers. I have my own server which I have full control over (which is where I switched to Nginx).

Proxying with Apache

Just a little VHost

<VirtualHost *:80>
 ServerName judofyr.net
 ServerAlias *.judofyr.net
 
 # Don't ask me why I use mod_rewrite,
 # I just prefer it over ProxyPass
 RewriteEngine on
 RewriteRule ^(.*) http://192.168.1.110$1 [P]
 
 # This will cause the Host-header to stay as the incoming
 # request, in stead of changing it to 192.168.1.110
 ProxyPreserveHost on
</VirtualHost>

Configuring Nginx

Thanks to many examples and pretty good documentation it’s very easy to configure Nginx. I stuck with the default config with only a few enchantments:

http {
    index     index.php index.html;
    charset   utf-8;
    include   sites/*;
}

PHP is great for small hacks, UTF-8 is a must and it’s always nice to split up the configurations in separate files. In sites/judofyr.net I have a minimal setup (which works like a charm):

server {
    listen        80;
    server_name   judofyr.net;
    access_log    /var/www/judofyr/logs/access.log
    root          /var/www/judofyr/public;
}  

Subdomains

Adding a new subdomain shouldn’t be harder than creating a new folder. So I wrote this wonderful configuration file (the folders are located in /var/www/sub):

server {
    listen                80; 
    server_name           yr.judofyr.net *.judofyr.net;
    fancyindex            on;
    fancyindex_exact_size off;
    
    # Extracts the subdomain to a variable
    if ($host ~ "^(.*).judofyr.net") {
        set $sub $1;
    }
    
    # If the directory doesn't exists, redirect to the main-page
    if (!-d /home/judofyr/judofyr.net/sub/$sub) {
        rewrite . http://judofyr.net/ redirect;
    }
    
    # Sets the correct root
    root /var/www/judofyr/sub/$sub; 
    
    # I'm using Lighttpd's spawn-fcgi to serve PHP-files
    location ~ \.php$ {
        include /usr/local/nginx/conf/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/judofyr/sub/$sub$fastcgi_script_name;
    }            
}  

Some notes:

It’s only going one way!

Down to every last byte, Nginx was built to scream.

Evan Miller

Nginx is getting more and more popular and is currently used by 1,018,503 domains, including YouPorn, hulu, WordPress.com, Kongregate and Mochi Media. Take a look at the example given here to see how much they care about the performance.

That’s the type of web server I want to use. Now I just need to convince the rest of the team…