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!"
end
- Test site starts with "ruby app.rb", you can wget the page to check content
- In same directory write config.ru for unicorn
- require 'sinatra'
set :env, :production
disable :runrequire './app.rb'
run Sinatra::Application
- require 'sinatra'
- 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/basic_unicorn.pid"preload_app true
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
endbefore_fork do |server, worker|
old_pid = "#{server.config[:pid]}.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
- worker_processes 8
- 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 Linuxclient_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!