Why?

Look here for a dozen reasons. Built by a lone Russian hacker, Nginx is a lightweight, open-source, fast and very extensible http server. Millions of sites rely on it and it is the preferred server for Rails apps according to the Rails team. We’ve traditionally used Passenger but recently have been migrating some of our apps to Nginx with fantastic results. We coupled this switch with a move from Phusion Passenger (mod_rails) to Unicorn to take advantage of its higher concurrency and better uptime management and you can read more about its advantages here.

How?

We’re going to show the process for those of you using Ubuntu 12.04 LTS. First, you’ll need to add the PPA for nginx which is done with the command:

~ $ sudo add-apt-repository ppa:nginx/stable
~ $ sudo apt-get update
~ $ sudo apt-get install nginx

If you get any errors like:

~ $ sudo: add-apt-repository: command not found

then you’ll need to run:

~ $ sudo apt-get install python-software-properties

and repeat the add-apt-repository and update commands.

Now, we’ll need to dive into the configuration files a little bit. First, we’ll take a look at /etc/nginx.conf. We’re going to mostly take cues from the sample nginx.conf file provided by the Unicorn team. You will want to go ahead and extract the upstream app_server and server blocks which we’re going to link to from another file by making sure

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

appears at the end of the file. To make this process easier, you might just cherrypick the features you like out of the Unicorn sample configuration since the default one is pretty spartan but has the Virtual Host setup already included. As always, if you are confused, you can check out the Nginx configuration help page for more examples and tips.

Once you’re satisfied with your nginx.conf file, you’ll want to do the following (replacing mojoware with your site’s name):

/etc/nginx $ cd sites-available/
/etc/nginx/sites-available $ sudo cp default mojoware
/etc/nginx/sites-available $ cd ../sites-enabled
/etc/nginx/sites-enabled $ sudo ln -s ../sites-available/mojoware mojoware
/etc/nginx/sites-enabled $ sudo rm default

This will copy the default configuration file for you to edit, will enable your copied site configuration and will disable the default site configuration. Go ahead and open your site configuration in either directory and start editing

/etc/nginx/sites-enabled $ sudo vim mojoware

Here’s our configuration for example, this is for a Rails app so there might be some differences if you have a static site or are using PHP or another language, but overall, your config will probably look similar.

upstream app_server {
    server unix:/home/mojoware/apps/mojoware_app/shared/sockets/unicorn.sock fail_timeout=0;
}
server {
    listen 80;
    server_name mojoware.com;

    client_max_body_size 4G;

    keepalive_timeout 5;

    access_log /var/log/nginx-access.log;
    error_log /var/log/nginx-error.log;

    root /home/mojoware/apps/mojoware_app/current/public;
    index index.html;

    try_files $uri/index.html $uri.html. $uri @app;

    location @app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://app_server;
    }

    location ~ ^/assets/ {
        expires 1y;
        add_header Cache-Control public;

        add_header ETag “”;
        break;
    }

    location ~ ^/(assets)/ {
        root /home/mojoware/apps/mojoware_app/current/public;
        gzip_static on;
        expires max;
        add_header Cache-Control public;
    }

    error_page 500 502 503 504 /500.html;
    location /500.html {
        root /home/mojoware/apps/mojoware_app/current/public;
    }
}

Now, at this point, you’ll need to go ahead and get Unicorn working before you’ll be able to see your app in the browser or anything. You’ll need to add the Unicorn gem to your Gemfile first.

~/apps/mojoware_app/current $ echo “gem ‘unicorn’” >> Gemfile
~/apps/mojoware_app/current $ bundle install

You’ll then need to make a new unicorn configuration file in config/

~/apps/mojoware_app/current $ touch config/unicorn.rb

You can go ahead and copy the sample unicorn.rb here and change settings based on the comments included with the file. We’re using Capistrano to do deploys, so all our folders for unicorn are in the ~/apps/mojoware_app/shared folder but you might end up just putting them in the /tmp/ folder instead. You’ll need tmp/sockets and tmp/pids at the minimum (make sure the unicorn.socks file is in the same path as in your sites-available script above). Once you have everything taken care of, the following should work:

~/apps/mojoware_app/current $ bundle exec unicorn -c config/unicorn.rb -D -E production

If you’re running in an environment different than production, you’ll want to switch that option out.

If all goes well, you should be able to visit your rails app now in your browser. You’ll probably want to install monit or something to monitor your nginx and unicorn processes but that will have to wait for another blog post!