A Do-It-Yourself Guide to Installing Ruby, Rails, and FastCGI

Here are some instructions for setting up Ruby, Ruby on Rails, FastCGI, and the Ruby/MySQL driver working with on OS X.

Preliminary Requirements:

In order to use these instructions, readers will need to have, at a minimum, the following software:

  • Mac OS X 10.3

  • Xcode Tools (we’ll only need the compiler)

Comfort using the Terminal is critical – don’t try this if the thought of using the sudo command seems frightening.

Getting the Source

While it’s possible to install both Ruby and mod_fastcgi from binary packages, these instructions focus on building the latest versions of the software from scratch. This is, after all, a do-it-yourself guide. For the record, however, here are the links to download the pre-compiled binary of Ruby 1.8.2 for OS X and the mod_fastcgi for Panther pre-compiled binaries. These binary distributions are not referenced by the main Ruby site, nor are they “Officially Sanctioned” by them, so we’ll just take the low road and compile directly from source.

Don’t worry – it’s not a big deal. Compiling Ruby and mod_fastcgi from source is surprisingly easy and only takes a few minutes. Besides, we’ll have to compile everything else from source as well. Below are direct links to the source code for each of the distributions we’ll need:

In order to setup FastCGI under Apache (an optional step), the following files will also be needed:

Additionally, consider downloading the MySQL/Ruby API Module, which allows Ruby scripts to talk with a MySQL Database. This module requires that MySQL (version 3.23.58 or newer) is installed:

Once we’ve downloaded all of the components, we’re ready to start compiling and installing them. The following steps will explain how to do it.

1. Compiling Ruby

Now that we have our source (ideally saved into a folder on the Desktop), we can open up Terminal, cd into that folder, and start compiling and installing.

We’ll start with Ruby itself, first. First, let’s unzip and untar the archive in one step, with the following command in Terminal:

tar xzvf ruby-1.8.2.tar.gz

Now switch into that folder with the cd command, like so:

cd ruby-1.8.2

It’s compile time. By specifying a prefix to the configure command below, we’re telling Ruby to install under /usr/local. This allows us to leave our original, Apple-installed Ruby alone, rather than replacing it. Just type the following commands, one by one, and we’ll have a working version of the latest Ruby:

./configure --prefix=/usr/local
sudo make install

We now have the latest Ruby, but it’s always worth testing to be sure. Type the following command at the prompt:

/usr/local/bin/ruby -v

We should see something like this:

ruby 1.8.2 (2004-12-25) [powerpc-darwin7.8.0]

Now we just need to set our shell’s path environment variable so that it will call the new version of Ruby first, rather than the Apple-distributed version. Use a text editor (vi, BBEdit, etc.) to create (or edit, if it already exists) a hidden file in our home folder named .bash_login (note the preceding “.”). To use create (or edit) the file using BBEdit, we’d use the following commands in the Terminal:

bbedit .bash_login

Enter the following two lines into the file:

export PATH

Because the .bash_login file is read before any other files when we login (or open a new Terminal window), additional path settings will be appended to the ones we’ve set here.

Note: If Bash isn’t the default login shell, the actual shell will need to be determined, and the appropriate rc file changed. People who have different shells will know if they need to do this, and what they need to do. Most people can ignore this.

Now close our existing Terminal window and open a new one in order to “refresh” our newly set path. In the new window, type the following line:

ruby -v

We should see the same result we saw earlier when specifying the exact path. If it’s see something else – namely an older version (say 1.6.8), we haven’t set our path correctly. This is important for the next steps, so make sure it’s right.

2. RubyGems

We’ll skip the niceties and jump right into the commands, step-by-step:

tar xzvf rubygems-0.8.8.tgz 
cd rubygems-0.8.8
sudo ruby setup.rb

That’s it! We should see a message reporting that we have successfully built RubyGem. Typing gem -v at the prompt should reveal that we’ve installed the latest version, 0.8.8.

3. Rails

Thanks to Gems, installing Rails is even easier:

sudo gem install rails

Answer yes by typing “Y” when prompted to all of the dependencies it asks about.

Pause or Continue?

At this point, we will have a fully functional version of Ruby and Ruby on Rails. If doing “normal” Rails development is all we’re wanting, this is probably all we’ll need. We don’t need to go any further, or install any additional software.

To build and test Rails applications, just launch the bundled WEBrick server from the command line, as specified in the Rails tutorials.

If, on the other hand, the plan is to deploy applications on a production server, we’ll need to configure Apache to support Virtual Hosts, creating a new VirtualHost configuration for each application we create. If this sounds tedious, it is, but this is how it works.

4. Running Rails with Apache

We can now create the framework for the Rails app (with the rails MyApp command) as described in the tutorials. We’ll need to know the full path to that folder for the next steps.

5a. Apache Virtual Hosting with OS X Client

Add these lines to the very bottom of our /etc/httpd/httpd.conf file using a text editor:

Listen 8000
  DocumentRoot /path/to/my/rails/app/public/
  <Directory /path/to/my/rails/app/public/>
    Options ExecCGI FollowSymLinks
    AddHandler cgi-script .cgi
    AllowOverride all
    Allow from all
    Order allow,deny

Important: Be sure to change /path/to/my/rails/app to the actual path of our rails app’s public folder in the example above. This is critical – it must point to the public folder, or else the app won’t work.

Now, save the file and restart Apache (I like to restart using the sudo apachectl graceful command).

5b. Apache Virtual Hosting with OS X Server

If we’re using Mac OS X Server, first create a new website using Server Admin. Set the Port to be 8000 and the Web Folder to point at the public folder beneath the Rails app as shown here.

Under the Options tab, enable the CGI Execution option as shown here.

For some reason, there isn’t a way to enable the use of .htaccess files – mandatory for a Rails app – when using Server Admin, so we’ll need to do it by hand. Using the text editor, open the configuration file for the server we just created in Server Admin. It will be located in /etc/httpd/sites/ and will have a name like 0003_servername.domain.com_8000_servername.domain.com.conf.

Once the file is open, locate the line that reads:

AllowOverride None

Change it to read:

AllowOverride All

Save the file and restart Apache (using the sudo apachectl graceful command).

Now we can just point a web browser at the virtual server we’ve just created and see Rails at work. If we’re running OS X client, the URL we’ll want to use will look like this:

If we’re using OS X Server, the URL will be the real name of our server followed by :8000.

Remember: We’ll need to create a new Virtual Host entry for each new Rails app we create.

It’s Slow!

Apache isn’t known for speed when executing CGI scripts, which is all Rails applications really are. This is why Movable Type (a Perl CGI script) is so horribly, horribly slow.

Fortunately, FastCGI can help. It creates a persistent version of the Rails applications we build. Not only are scripts running under FastCGI many times (even when not under heavy load), but Ruby scripts can also maintain persistent database connection pools for speedier database interactivity.

6. FastCGI

Let’s untar and install FastCGI:

tar xzvf fcgi-2.4.0.tar.gz 
cd fcgi-2.4.0
./configure --prefix=/usr/local
sudo make
sudo make install

Now we need to instal the FastCGI bindings for Ruby:

tar xzvf ruby-fcgi-0.8.5.tar.gz
cd ruby-fcgi-0.8.5
/usr/local/bin/ruby install.rb config --prefix=/usr/local/
ruby install.rb setup
sudo ruby install.rb install

Then, just to make sure that Rails knows about and can access these libraries, we’ll install them to Rails with Gems:

sudo gem install fcgi

The last step in enabling FastCGI under Apache is to compile and install the mod_fastcgi Apache module as a DSO:

tar xzvf mod_fastcgi-2.4.2.tar.gz
cd mod_fastcgi-2.4.2
apxs -o mod_fastcgi.so -c *.c
sudo apxs -i -a -n fastcgi mod_fastcgi.so

Open up the main apache configuration file (located in /etc/httpd/httpd.conf on both OS X client and Server), and add the following lines:

<IfModule mod_fastcgi.c></p>
  FastCgiIpcDir /tmp/fcgi_ipc/
  AddHandler fastcgi-script .fcgi

In order to enable FastCGI for the Rails application, edit the .htaccess file in the public folder, and find the line that reads:

RewriteRule ^(.*)$ /dispatch.cgi?$1 [QSA,L]

Change it to read:

RewriteRule ^(.*)$ /dispatch.fcgi?$1 [QSA,L]

Restart Apache with he sudo apachectl graceful command, and we’re up and running with FastCGI.

7. The MySQL/Ruby API

If we’re planning to build Ruby applications won’t live within the Rails framework but will need to access a MySQL database, we’ll need the MySQL/Ruby API. This API depends on the existence of MySQL on the local machine. If it’s not or cannot be installed, take a look into the Ruby/MySQL API, which has some inbuilt MySQL code and should work without a local MySQL install.

So let’s install the MySQL/Ruby API:

tar xzvf mysql-ruby-2.5.2.tar.gz
cd mysql-ruby-2.5.2
/usr/local/bin/ruby extconf.rb --with-mysql-dir=/usr/local/mysql

The previous command expects that our MySQL installation is under /usr/local/mysql. If it’s somewhere else, just specify the location in the command above.

Assuming that MySQL is running, we can test the new API before installing it:

ruby -I. ./test.rb <em>hostname username password</em>

Be sure to substitute the machine’s hostname and the MySQL username and password when entering the line above. If that worked, we’re finally ready to install the API:

sudo make install

We can now get a connection to a MySQL server in our Ruby script like this:

require 'mysql'
con = Mysql.new(</p>
  "mydatabase"<br />
)<br />

More information about this API can be found at the Ruby/MySQL site.

Are We There Yet?

We’re done! We now have a fully functional Ruby installation with the MySQL API. We’ve also got Ruby on Rails being delivered via FastCGI for optimal performance.

More articles in the Archive →