LINUX – Setup Ruby/Sinatra/Unicorn/NGINX server

Quick intro in angry split personality QA format:

Ya What? Unicorns? Sinatra?? Nuggex??? You’re just stringing random words together! Badly!

Ok, it’s a lot of tech words, here’s the breakdown:

  • Ruby – Lovely scripting language that makes it easy to write clear concise code
  • Sinatra – Framework for creating web applications in Ruby, very simple to use
  • Unicorn – Quick and reliable HTTP server for Ruby
  • NGINX – (n-gin-x) HTTP server and reverse proxy, ultra quick for static files

Why? You could be drinking beer at home?

Using Unicorn and NGINX together we get the best of both for hosting our site, Unicorn handles the requests to the Ruby app and NGINX handles the static public files (Images/CSS/JS). GitHub posted a blog why they switched to Unicorn and the benefits.

Fine! Lets get this over with then!

Steps in this sample done in AWS EC2 Ubuntu 11.10 image:

  • Install NGINX
  • Start NGINX and test – “/etc/init.d/nginx start” but location of nginx depends on distro
  • Install Ruby – “sudo apt-get install ruby1.9.1-dev” (actually installs 1.9.2), need dev version for gems
  • Install Ruby gems
    • Install make – “sudo apt-get install make” (may already be installed)
    • Install gcc – “sudo apt-get install gcc” (may already be installed)
    • Install gems – “sudo gem install unicorn sinatra”
  • Check unicorn is working “unicorn -version” (if not check Ruby gems installed and are in path)
  • Make simple sinatra app
    • make a folder for your app e.g. ruby1
    • In the folder write a file “app.rb” with the following content:
    • require ‘rubygems’
      require ‘sinatra’

      get ‘/’ do
        “hello world!”

    • Test site starts with “ruby app.rb“, you can wget the page to check content
  • In same directory write for unicorn
    • require ‘sinatra’

      set :env, :production
      disable :run

      require ‘./app.rb’

      run Sinatra::Application

  • In same directory write unicorn.conf for unicorn
    • worker_processes 8
      working_directory “/home/USER/APPDIR”
      listen ‘unix:/tmp/basic.sock’, :backlog => 512
      timeout 120
      pid “/var/run/unicorn/”

      preload_app true
      if GC.respond_to?(:copy_on_write_friendly=)
        GC.copy_on_write_friendly = true

      before_fork do |server, worker|
        old_pid = “#{server.config[:pid]}.oldbin”
        if File.exists?(old_pid) && != old_pid
          rescue Errno::ENOENT, Errno::ESRCH
            # someone else did our job for us

  • Create unicorn running dir
    • “mkdir /var/run/unicorn”
    • Set perms so unicorn running user can write to this dir
  • Start unicorn
    • “unicorn -c unicorn.conf &” should show worker threading starting
  • Add new NGINX conf
    • In /etc/nginx/sites-enabled/, write a file unicorn
    • upstream app_server {
        server unix:/tmp/basic.sock fail_timeout=0;

      server {
        listen 80 default deferred; # for Linux

        client_max_body_size 4G;
        server_name _;

        keepalive_timeout 5;

        # path for static files
        root /home/USERNAME/basic/public;

        # Prefer to serve static files directly from nginx to avoid unnecessary
        # data copies from the application server.
        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;

  • Restart nginx – “sudo service nginx restart”
  • Test your site!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s