Tuesday, March 15, 2011

Deploy Sinatra to Ubuntu Maverick

Sinatra is a great little ruby framework that's perfect for when Rails is too much. Deploying an app you write is a snap using Heroku but what do you do if that's not an option for you? This Starter's Guide hopes to help you with that. When done, you'll have Apache 2 and Sinatra running together nicely with the help of Phusion Passenger. We'll cover Nginx in future tutorial. So let's get started!

Step 1: Set up your Ubuntu Gnu/Linux 10.10 VPS
I usually use Slicehost or Linode, but newbies should also take a look at Bluebox. For instructions on setting up your VPS, take a look at this post. It's a little old but should still work fine.

Step 2: Install Ruby 1.9.2
The next thing we need to do is download and compile Ruby. We could use RVM here as well, but since we won't be switching versions of ruby around, we'll stick with the simple method. From the command line let's grab the latest version and install it:
wget ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-1.9.2-p180.tar.gz
tar xvzf ruby-1.9.2-p180.tar.gz
cd ruby-1.9.2-p180./configure --prefix=/usr/local/ruby
make
sudo make install

Next, open up your favorite text editor and change your path in /etc/environment to
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/ruby/bin"

Then, as root, run this command:
source /etc/environment

Lastly, create symlinks so you can easily access your ruby install:
sudo ln -s /usr/local/ruby/bin/ruby /usr/local/bin/ruby 
sudo ln -s /usr/local/ruby/bin/gem /usr/bin/gem

3. We've got ruby, let's grab Sinatra
Once we've got ruby installed, we can start installing the gems needed to get our Sinatra app running. Depending on *your* application, you may need other gems as well.
sudo gem install sinatra

Let's create a basic sinatra app called hi.rb and put it in /var/www/sinatra_test
sudo mkdir -p /var/www/sinatra_test
sudo vi /var/www/sinatra_test/hi.rb

Here's a very basic Sinatra app taken almost verbatim from the homepage:
require 'rubygems'
require 'sinatra'
get '/' do  
  "Hello from Sinatra!"
end

Let's test our app out by running it and looking at it in the browser:
$ ruby -rubygems hi.rb
== Sinatra has taken the stage ...
>> Listening on 0.0.0.0:4567

Note that if you've got a firewall setup you'll need to make sure port 4567 is available!

Step 4: Install Apache and Passenger
Next up we'll need to install Apache 2 and Passenger 3.
sudo apt-get install libcurl4-openssl-dev apache2-mpm-prefork apache2-prefork-dev libapr1-dev libaprutil1-dev
sudo gem install passenger
sudo passenger-install-apache2-module 

We're going to deviate a little from the official passneger instructions by splitting the necessary lines into an apache module. This way you can enable and disable passenger as you would any other module. Add these lines (noting that they will differ depending on the version of Ruby and Passenger you have) to your /etc/apache2/mods-available/passenger.conf file:
PassengerRoot /usr/local/ruby/lib/ruby/gems/1.9.1/gems/passenger-3.0.5   
PassengerRuby /usr/local/ruby/bin/ruby

Next add this line to your /etc/apache2/mods-available/passenger.load file:
LoadModule passenger_module /usr/local/ruby/lib/ruby/gems/1.9.1/gems/passenger-3.0.5/ext/apache2/mod_passenger.so

Lastly, let's enable the modules:
sudo a2enmod passenger

Step 5: Wire it all up.
We're going to use a config.ru file and create a new site for apache in order to wire this up.

First, in your directory root (/var/www/sinatra_test) create a config.ru file with the following contents:
require 'rubygems'
require 'sinatra'
require File.dirname(__FILE__) + "/hi.rb"
run Sinatra::Application

Next, let's create a new file in /etc/apache2/sites-available called sinatra and use the following contents to hook it up (you'll of course want to replace the ServerName, DocumentRoot, and Directory with information specific to your setup):
<VirtualHost *:80>      
 ServerName blog.econify.com      
 DocumentRoot /var/www/sinatra_test/public      
 <Directory /var/www/sinatra_test/public>         
   AllowOverride all         
   Options -MultiViews      
 </Directory>   
</VirtualHost>

Note, that if you deploy with Capistrano, your paths will likely be slightly different.

Let's enable the site and restart Apache:
sudo a2ensite sinatra
sudo /etc/init.d/apache2 stop
sudo /etc/init.d/apache2 start

Once the above is done, you should have a fully functional Sinatra app running on Apache2 with Phusion Passenger on port 80. There are of course other ways to connect and deploy Sinatra. Heroku remains an excellent choice, but if for some reason that's not in your toolbox, we hope the above provides a useful starting point.

2 comments:

  1. There is a slight problem installing, with the gem command being unhappy about not finding zlib. To fix this, you need to edit ext/Setup and uncomment the line with #zlib. This will statically link zlib against ruby and gem so that you can install gems.

    See: http://stackoverflow.com/questions/769496/ubuntu-noob-rails-install-fails-on-zlib

    ReplyDelete
  2. Good work on the documentation. I went through this on an RHEL 6 VM. Faced the issue that Geoff mentioned. I tried your solution but no luck. I then did a yum install zlib-devel and proceeded to reinstall ruby. This worked for me.

    ReplyDelete