Let’s have fun: Rails 2.3.5 + nginx + Passenger on a G4 Cube with Tiger

Last week-end, I purchased a used PowerMac G4 Cube, an iconic product in the Mac community.  I was wondering what I could do with it, given its performance limitation.

I thought of using it to rip some of my DVDs so I could watch the TV shows on my iPad.  But the cube does not have the power to encode in X264.  A 24 minutes episode was requiring 8 hours of encoding… That’s insane!

So then I came up with the idea of using it as a torrent downloader.  I would submit download request through a web interface or by placing a torrent file in a shared folder.  The web interface would also show the current and past downloads. I am planning to have Transmission running and using their API to interface with it, using one the following Github projects:

Since I spend almost all my time in Ruby on Rails, why not setting up Rails on the cube, with nginx, Passenger and SQLite.


XCode installation.  XCode can be found on the Tiger install disc.  We do not need to have the latest and greates, we simply need the compile and some development libraries installed.  I did not install everything, just the following:

  • Developer Tools Software
  • gcc 4.0
  • gcc 3.3
  • Soware Development Kits

Ruby & Rubygems

I could install Ruby using the great RubyOSX one-click install, but I wanted to make sure I had the full control on what I install.  So I decided to install sources and compile everything.

Tiger comes with a very old version of Ruby: 1.8.2. Let’s upgrade it to a more recent version.  I followed Hivelogic instructions for doing so.

The difference is that I chose to install patch 399 of ruby 1.8.6: 

curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p399.tar.gz

And for Rubygems, I chose to install the latest version, 1.3.6:

curl -O http://production.cf.rubygems.org/rubygems/rubygems-1.3.6.tgz

Be patient when compiling Ruby… It’s only a 450Mhz PowerPC computer!


Now that we have rubygems, let’s install the sqlite3 adapter.

sudo gem install sqlite3-ruby


There is a good chance that we will need git for some plugins for our Rails application.  So let’s install this as well.

cd /usr/local/src
curl -O http://kernel.org/pub/software/scm/git/git-1.7.1.tar.gz
tar xzvf git-1.7.1.tar.gz 
cd git-1.7.1
make configure
./configure --prefix=/usr/local 
sudo make install</pre>


Now, the “piece de resistance”: Rails.  This is pretty straight forward.  Let’s install it, without the documentation.  Development will not be done on the G4 Cube.  We will use Capistrano to remotely deploy our apps on it.

sudo gem install -V rails -v 2.3.5 --no-rdoc --no-ri


We need to install Passenger first, because we will need a passenger-nginx module later.

sudo gem install passenger


We could have installed nginx using Passenger, but let’s take the complex route (Passenger has not been tested on Tiger).

First, let’s install nginx.

cd /usr/local/src
curl -O http://nginx.org/download/nginx-0.8.36.tar.gz
tar xvfz nginx-0.8.36.tar.gz
cd nginx-0.8.36
sudo ./configure --pid-path=/usr/local/nginx/logs/nginx.pid --sbin-path=/usr/local/sbin/nginx --with-md5=/usr/lib --with-sha1=/usr/lib --with-http_ssl_module  --with-http_dav_module --without-http_rewrite_module --add-module=`passenger-config --root`/ext/nginx
sudo make
sudo make install

When running “configure”, at some point, you should get *** Phusion Passenger support files have been successfully compiled ***. That’s a good sign!

Now let’s create a script to automatically start nginx (thanks to Trevor for some hints).

Using a file editor, create file /Library/LaunchDaemons/nginx.plist and put the following content in it:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

Load the daemon description:

sudo launchctl load /Library/LaunchDaemons/nginx.plist

Nginx should start automatically. You can check by looking the processes and see if the nginx server is there:

ps -aux | grep nginx

If nginx did not start, look at the possible errors in /usr/local/nginx/logs/error.log.

If you need to start or stop nginx manually, here’s how to do it:

sudo nginx -s stop
sudo nginx

Test application

Let’s create a dummy Rails app to test our set-up.

cd ~
rails foo
cd foo
script/generate scaffold bar title:string description:text
rake db:create
rake db:migrate
sed 's/# map.root/map.root/g' config/routes.rb | sed 's/welcome/bars/g' > config/routes.rb
rm public/index.html

Now, let’s configure nginx. Instead of creating virtual servers for each Rails app, let’s put them all under the same virtual server. This way, we won’t have to create special hostnames and different server sections in the nginx configuration. And we will be able to access the applications by pointing to the G4 Cube ip address. We just need to make sure Passenger is aware of that by using the passenger_base_uri directive.

So let’s create a symbolic link in the root html directory:

cd /usr/local/nginx/html
sudo ln -s ~/foo/public/ foo

Make sure the nginx configuration file (/usr/local/nginx/conf/nginx.conf) looks like something like this:

worker_processes  1;

events {
    worker_connections  1024;

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    gzip  on;

    passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11;
    passenger_ruby /usr/local/bin/ruby;

    server {
        listen       80;
        server_name  localhost;

        passenger_enabled on;
        passenger_base_uri /foo;
        rails_env development;
        root /usr/local/nginx/html;

Check the location of your passenger root by running this command:

passenger-config --root

If you loaded the launch daemon script, nginx is most likely running at the moment. Let’s reload the configuration file:

sudo nginx -s reload

Now, the moment of truth. Rush to Safari and go to http://localhost/foo. After a few seconds (Passenger must start the app), you should get the bars scaffold.

Excellent! We now have a fully functional system for hosting utility apps on my home network. The next step is to write the apps!

See ya next time!