This website is written in Ruby using the Sinatra framework and hosted with Passenger / Nginx on the Raspberry Pi ( temporarily not on a Pi! ) assisted by Cloudflare and a dash of jsDelivr

Ruby with Nginx/Passenger

When I first set up this blog, I happened upon Thin and assumed it to be the best solution for serving it up to the web. I was wrong. Thin is great, and has its place, but it has a simple requirement that the Pi isn't well suited to satisfy; it needs a load balancer.

Thin seems aimed at running one or more instance of an application on one or more ports, on one or more servers, and letting an Apache, or other, load balancer sort out the chaos into a single web front-end. This is great in principle, but for something as lightweight as this blog, on a Raspberry Pi no less... it just doesn't really work out. I could spool up muliple "thins" with no problem, and proxy them with Apache using a load-balancer. But performance was pretty poor. A load balancer is an extra step, and clearly a step to much for the Pi!

Running one instance of your application isn't great, either. Unless you fudge together something with async-sinatra, any request to your application will prevent it answering other requests until it's done. IE: your application will be single-threaded, and if there's more than just you using it, it'll run poorly, very poorly.

Enter Passenger. Passenger handles the task of running multiple instances of your application pretty much transparently. For anything you'd want to run on the Pi, the defaults seem to suffice. It runs beautifully as a plugin to Nginx (a great little HTTP server) which it will even download, compile, install and configure for you. To actually get a site up and running once it's done its thing is dead simple, and getting an init script set up isn't much trickier.

Getting Started

First up you're going to need Ruby. I highly recommend setting up RVM and installing Ruby 1.9.x, but I wont cover the installation of these in this guide. See For the lazy, you can probably just run:

\curl -L | bash -s stable --autolibs=enabled --ruby=1.9.3

Installing Passenger

Once your Ruby weapon of choice is installed and ready, you'll need to install Passenger. You can do this pretty easily with:

gem install passenger

The gem will download and install itself, along with a few tools for getting set up with various HTTP servers.

Installing Nginx

Getting Nginx installed is then as simple as running:

sudo passenger-install-nginx-module

Or if you used RVM:

rvmsudo passenger-install-nginx-module

This installer script will tell you how to install any dependencies you might be missing.

Once you've solved any dependency woes, you'll be prompted for an install prefix. I use "/usr/nginx" instead of "/opt/nginx" to be awkward.

Note: I found that Nginx wouldn't compile on my 256mb Pi due to a lack of memory. I had to migrate everything to my Rev 2 Pi. Your mileage may vary, however!

Configuring your first application

Setting up your first application and getting it to serve pages to the web is simple. You need to open "/usr/nginx/conf/nginx.conf". If you open this with vim you can hit shift+G to skip to the bottom. Here you should put something along the lines of:

server {
listen 80;
root /home/pi/your_app/public;
passenger_enabled on;

Make sure you point the "root" to the "public" directory of your Sinatra or Rails application, and make sure you have a ready to go. I also set up a Gemfile for each of my Apps, Passenger will check this and try to use the listed gems; throwing errors if they're not available. If you get in the habit of using a Gemfile, you can simply run "bundle install" if you need to move your App to a new Pi.

When you're happy that your application is running stably, I'd recommend you save your SD card a little wear by adding the following to your nginx.conf:

error_log /dev/null;
access_log off;

You can now start nginx using /usr/nginx/sbin/nginx. If you want to stop or reload Nginx you can use the "-s" (signal) switch like so: /usr/nginx/sbin/nginx -s reload

Advanced Server Setup

If you want to configure new sites without dipping into nginx.conf you should add this line below the closing } at the bottom of nginx.conf:

include /usr/nginx/servers/*.conf

Make sure you also make the /usr/nginx/servers/ directory, and simply place your server configs there in .conf files. Rename them to .off or and they wont be loaded when you reload Nginx!

If you want to use an Init script then I recommend the following:

I dropped this script into /etc/init.d/nginx and changed all references to /opt/nginx over to my /usr/nginx directory. You can then:

sudo service nginx start
chkconfig nginx on

« Back to index Posted on 2013-04-28 by