howtos

Ruby on Rails on XAMPP with FastCGI for Ubuntu Hoary

Introduction

I've done a lot of tinkering with Ruby on Rails recently, and thought it might be worth sharing my experiences with the wider world (I get a few hits on my website from people looking for "xampp+ruby", so thought I might be able to help those folks out).

This isn't a full tutorial, and I'll assume you understand how to create a database and tables in MySQL, and navigate your way round a command line. I also won't go into the ins and outs of Rails, but will point at far better tutorials that should help you get to grips with it.

Getting Ruby on Rails working is relatively straightforward. I'll talk about getting it going on Ubuntu, the Linux distribution I use for development work. The software you'll need to get started is as follows:

  • Ruby - a full install
  • Rails - a Ruby package available via the gem tool (which you'll need to install as well)
  • XAMPP - this is a bundle of software including Apache (the web server to run your Rails application off of) and MySQL (the database back-end for your Rails application)

Once I installed this lot, I wrote my first Rails application to prove to myself it was working; so this tutorial will follow the same pattern, and I'll give some minimal instructions about creating a minimal application to prove Rails is working.

Then, optionally, you can install FastCGI to improve the performance of Rails applications (by default, Rails makes CGI applications). To get FastCGI working with Rails, you need the following:

  • FastCGI - to improve performance of your Rails application; this works as an Apache module
  • Ruby FastCGI bindings - so Rails can make use of FastCGI

Installing Ruby

I followed these instructions to install a full Ruby. If you are using Ubuntu, this boils down to running the following command as root:

apt-get install \
irb1.8 \
libbigdecimal-ruby1.8 \
libcurses-ruby1.8 \
libdbm-ruby1.8 \
libdl-ruby1.8 \
libdrb-ruby1.8 \
liberb-ruby1.8 \
libgdbm-ruby1.8 \
libiconv-ruby1.8 \
libopenssl-ruby1.8 \
libpty-ruby1.8 \
libracc-runtime-ruby1.8 \
libreadline-ruby1.8 \
librexml-ruby1.8 \
libruby1.8 \
libruby1.8-dbg \
libsdbm-ruby1.8 \
libsoap-ruby1.8 \
libstrscan-ruby1.8 \
libsyslog-ruby1.8 \
libtest-unit-ruby1.8 \
libwebrick-ruby1.8 \
libxmlrpc-ruby1.8 \
libyaml-ruby1.8 \
libzlib-ruby1.8 \
rdoc1.8 \
ri1.8 \
ri \
rdoc \
ruby \
ruby1.8 \
ruby1.8-dev \
libmysql-ruby1.8 \
ruby1.8-examples

Installing Rails

Rails can be installed via the gem tool for Ruby, which is kind of an apt for Ruby. It is possible that there are Debian packages for Rails, but I've been using the manual install method so I get the latest Rails.

Before you can install Rails, you will need to download and install gem first, like this:

  1. Grab the latest tarball version from http://rubyforge.org/frs/?group_id=126
  2. Unpack it somewhere:
    cd ~
    tar zxvf rubygems-0.8.11.tgz
  3. As root, connect to the unpacked directory and run:
    ruby setup.rb
  4. Once you've done this, you can get the latest version at any time using this command as root:
    gem install rubygems

To install Rails, as root do:

  • gem install rails -v 0.13.0

Note that I'd suggest installing this version of Rails (0.13.0), as at the time of writing the latest version (0.13.1) is not supported under the version of Ruby packaged for Ubuntu. If you install this later version, it will refuse to work with the installed version of Ruby.

Installing XAMPP

XAMPP is a really nice way of getting a LAMP stack up and working quickly. It comes packaged with Apache, MySQL, PHP (4 and 5), Perl, phpmyadmin, and phpsqlliteadmin, so you get a full stack up and running quickly. It's not suitable for production use out of the box, but can be tailored to make it secure.

To install XAMPP, follow these instructions:

  1. Download it from here. I used version 1.4.14.
  2. Unpack it into the /opt directory as root:
    cp xampp-linux-1.4.14.tar.gz /opt
    cd /opt
    tar zxvf xampp-linux-1.4.14.tar.gz
  3. Start XAMPP as root using:
    /opt/lampp/lampp start
  4. That's it.

Full instructions for running it are given on the XAMPP website.

Creating a first Rails application

My first Rails application was built with help from these instructions, which are very good. However, I wanted to run my applications with Apache, rather than the Webrick built-in web server which Rails is bundled with. So here's my set of minimal instructions for writing a Rails application to run inside Apache.

  1. First thing you'll need is a database. Create one in MySQL called cdcollection.
  2. Create a user with privileges on that database only: I called my user cdcollection. As far as I can tell, you only need to give this user SELECT, UPDATE, DELETE and INSERT privileges on the database.
  3. One other wrinkle: the MySQL client libraries in Ruby do not support the latest MySQL authentication protocol, as used by MySQL 4.1 (and included in XAMPP 1.4.14). So that our cdcollection user can connect to the database, you need to update the mysql.user table like this:
    USE mysql;
    UPDATE user SET password = OLD_PASSWORD(<password>) WHERE user='cdcollection';

    FLUSH PRIVILEGES;
  4. Add a table to the database called cds. Rails is quite exacting about what you call your database tables, and it's easiest to use plurals (this upsets me too, but let it pass). Give it three fields: id (int, unsigned, not null, autoincrement, primary key), title (varchar, 255 characters, not null), artist (varchar, 255 characters, not null).
  5. Put some records into the cds table so Rails has something to display.

We're now ready to create our Rails application.

  1. Create the base application like this:
    rails ~/cdcollection
    The argument you pass to the rails command specifies the directory where the base application should be installed.  Note that this is outside XAMPP's DocumentRoot directory: I tend to build the application externally to XAMPP, and symlink it into the DocumentRoot (which we'll do later).
  2. Calling this command creates a standard directory structure for your application, common to all Rails applications. This directory structure is described here.
  3. The next things we have to edit are the "shebang" lines at the top of the scripts which Rails relies on. You can find where Ruby is located using whereis ruby, which should give you the path you need to supply as the shebang for the scripts. You can do a global replace using this Ruby command:
    ruby -i -pe 'gsub!("#!/usr/local/bin/ruby", "#!/usr/bin/ruby")' ~/cdcollection/public/dispatch.* ~/cdcollection/script/*
    (I've found that the default shebang in Rails 0.13.0 is /usr/bin/ruby1.8, which works fine in Ubuntu.)
  4. Edit the database configuration file (~/cdcollection/config/database.yml) so it looks like this:
    development:
    adapter: mysql
    database: cdcollection
    host: localhost
    username: cdcollection
    password: <password>
    socket: /opt/lampp/var/mysql/mysql.sock
    Note the extra socket line in this file: this is necessary because XAMPP's MySQL socket runs in a different location from the default, so you have to tell Ruby where the socket is.
    Note that I haven't edited the production and test database environments specified in this configuration file: you will need to do this once you start serious development.
  5. Create an initial model, controller and view for our cds table. Rails provides scripts for creating basic MVC code for doing CRUD operations on a database table.
    cd ~/cdcollection
    ruby script/generate scaffold cd

    This operation adds some files into the app directory. We now have enough code to run our application.

The last step is to link our directory into our XAMPP DocumentRoot and set its permissions, so we can do something with it:

  1. ln -s <path_to_home_dir>/cdcollection/public /opt/lampp/htdocs/cdcollection
  2. chown -R nobody.users <path_to_home_dir>/cdcollection
  3. chmod -R g+w <path_to_home_dir>/cdcollection

To see the application, navigate to http://localhost/cdcollection/cds. Note that if you go to http://localhost/cdcollection/, you will just get the default "Rails is working" message.

Hopefully, you should see a list of the CDs you entered into your database, and be able to add, edit, update and delete them. This means Rails is working fine, using CGI to run.

You can now follow these excellent tutorials to improve your Rails application:

The Rails API documentation is also very good, and you will find this online book handy if you are also trying to learn Ruby at the same time.

Installing FastCGI

The next step is to improve performance of our Rails application so it runs under FastCGI, rather than standard CGI. (NB it is also theoretically possible to run Rails applications under mod_ruby, but I couldn't get this working.) Here's an explanation of FastCGI and what it's for.

Because I was running XAMPP, and there's no FastCGI package for XAMPP, I built one from the FastCGI source. The first thing you need to do is get the XAMPP Development package and unpack this on top of your XAMPP installation:

  1. Get the development package from:
    http://www.apachefriends.org/en/xampp-linux.html
  2. Unpack it:
    cp xampp-linux-devel-1.4.14.tar.gz /opt
    cd /opt
    tar zxvf xampp-linux-devel-1.4.14.tar.gz

Next thing you need is the source distribution of FastCGI:

  1. Download the tarball from http://fastcgi.com/dist/; you need the mod_fastcgi tarball (I used version 2.4.2).
  2. tar zxvf mod_fastcgi-2.4.2.tar.gz
  3. cd mod_fastcgi-2.4.2
  4. mv Makefile.AP2 Makefile
  5. Edit Makefile and change the top_dir variable so its value is /opt/lampp
  6. make
  7. make install

This installs a mod_fastcgi module into XAMPP's modules directory (/opt/lampp/modules/mod_fastcgi.so).

Now edit Apache's configuration file (/opt/lampp/etc/httpd.conf) so that this module is loaded. I did this by adding the following lines to the file:

LoadModule fastcgi_module modules/mod_fastcgi.so
<IfModule mod_fastcgi.c>
  FastCgiIpcDir /opt/lampp/tmp/fcgi/
  AddHandler fastcgi-script .fcgi
</IfModule>

You will also need to add the fcgi directory to your XAMPP installation and set its permissions, i.e.

mkdir /opt/lampp/tmp/fcgi
mkdir /opt/lampp/tmp/fcgi/dynamic
chown -R nobody.root /opt/lampp/tmp/fcgi
chmod -R 777 /opt/lamp/tmp/fcgi

Note that this gives read/write/execute permissions on this directory to anybody. I'm sure there is a better way to do this, and welcome suggestions :)

You will need to reload Apache for this to take effect. Hopefully, you should now have mod_fastcgi installed and working. Check the error_log file just to make sure FastCGI is not throwing any errors.

Installing Ruby FastCGI bindings

We will also need the FastCGI development kit to install the Ruby bindings for FastCGI:

  1. Get the source tarball from http://fastcgi.com/dist/. You will need the fcgi tarball.
  2. tar zxvf fcgi-2.4.0.tar.gz
  3. cd fcgi-2.4.0
  4. ./configure --prefix=/opt/fastcgi
  5. make install

Note that this installs the development kit into /opt/fastcgi.

To install the Ruby bindings for FastCGI:

  1. Get the latest tarball of ruby-fcgi from http://sugi.nemui.org/pub/ruby/fcgi/. I got it working with version 0.8.6.
  2. tar zxvf ruby-fcgi-0.8.6.tar.gz
  3. cd ruby-fcgi-0.8.6
  4. ruby install.rb config -- --with-fcgi-include=/opt/fastcgi/include --with-fcgi-lib=/opt/fastcgi/lib
  5. ruby install.rb setup
  6. ruby install.rb install

Editing the Rails application to use FastCGI

The last step is to configure the Rails application to make use of FastCGI. You can do this by editing the ~/cdcollection/public/.htaccess file as follows:

Change the line:
RewriteRule ^(.*)$ /dispatch.cgi?$1 [QSA,L]
to
RewriteRule ^(.*)$ /dispatch.fcgi?$1 [QSA,L]

If you now return to your application in the browser, you should see a noticeable improvement in speed.

That's about all you need to do to get Rails running under FastCGI on Ubuntu. It's a bit scrappy and complicated at the moment, but hopefully before too long someone will start making the packages we need for this...

Syndicate content