Ruby on Rails - Setting things up on Fedora

Fedora is Linux and rails is rails. There is lots here that might be helpful to someone setting up rails on a non-fedora system. However, I won't pretend to give generic instructions, just a play by play of what I actually did to get rails set up to run on an "out of the box" fedora install running Fedora Core 8. This is first being written in July of 2008; if you are reading this in 2013, the rest of the world may be on to new and better ways. I say "out of the box" because this is my home system, which I have NOT been keeping up to date via yum. As you will see, I do use yum to install RPM packages. Part of the game is to see if I can manage a rails setup without installing anything via "gem". (The answer seems to be NO now that the dust has cleared.) Not that I have any bias against gem per se, but I have been warned that you are well advised to do things one way or the other, or risk conflict and confusion.

Part of the motivation for this (apart from getting rails onto my home machine) is to figure out how to untangle another system that has an ancient rails install, and is now screwed up in weird and wonderful ways. I should point out that there are other options, such as using gem exclusively, or installing from source.

Get ruby up to date

I have ruby already (version 1.8.6), but I do yum update ruby anyway, and get a more recent patch level of ruby 1.8.6. I also do:
yum install ruby-irb
yum install ruby-rdoc
These would ordinarily be part of any generic ruby install, but for some reason were not on my system. At this point, the directory /usr/lib/ruby/gems does not yet exist. Also, the directories /usr/lib/ruby/site_ruby /usr/lib/ruby/site_ruby/1.8 exist, but are empty. (I mention this because the chaos in the above mentioned "screwed-up" fedora system involves things in these directories, sorry for the digression).

Get the rails package set

As of July, 2008, it is possible to get rails via yum as the package rubygem-rails. (It is also possible as of this time to be running Fedora Core 9, but I am not, largely because of some Nvidia graphics issues that have no relevance to rails ... I don't know what might be different if you were working with Core 9.)

The command yum install rubygem-rails pulls in a collection of dependent packages, as follows:

Installing:
 rubygem-rails           noarch     2.0.2-2.fc8      updates           382 k
Installing for dependencies:
 rubygem-actionmailer    noarch     2.0.2-2.fc8      updates           507 k
 rubygem-actionpack      noarch     2.0.2-2.fc8      updates           2.0 M
 rubygem-activerecord    noarch     2.0.2-2.fc8      updates           1.3 M
 rubygem-activeresource  noarch     2.0.2-2.fc8      updates           148 k
 rubygem-activesupport   noarch     2.0.2-1.fc8      updates           790 k
 rubygem-rake            noarch     0.8.1-2.fc8      updates           336 k
 rubygems                noarch     0.9.4-1.fc8      fedora            498 k

This creates the directory /usr/lib/ruby/gems. and puts the bulk of what it installs into /usr/lib/ruby/gems/1.8/gems.

Some stuff also appears in /usr/lib/ruby/site_ruby/1.8

Test fly rails on port 3000

Now, I pick a spot in my system and do the following:
mkdir rails
cd rails
rails demo
cd demo
script/server
A Webrick server fires up on port 3000, and when I point my browser at http://localhost:3000, Shazam!: I see the friendly rails greeting page.
So far so good.

What about mongrel?

I was under the impression that I would be running mongrel, rather than webrick at this point, but a little sniffing around convinces me that mongrel is not part of the deal thus far. So, since I have a nice working development environment, no sense leaving things rest there, let's issue the command yum install rubygem-mongrel, this grabs several packages (and it comes in a x86_64 flavor, since mongrel includes compiled code):
Installing:
 rubygem-mongrel         x86_64     1.0.1-5.fc8      fedora            497 k
Installing for dependencies:
 rubygem-daemons         noarch     1.0.7-2.fc8      fedora            126 k
 rubygem-fastthread      x86_64     1.0-1.fc8        fedora             42 k
 rubygem-gem_plugin      noarch     0.2.2-2.fc8      fedora            109 k
I stop the webrick server, and reissue the command script/server and voila! I get a mongrel server (and the advice that I can use the command script/server webrick to insist on a webrick server if I should so choose. All wonderful thus far.

You can also start mongrel via mongrel_rails start, and I am not clear on the difference between this and the above; it work either way.

My /usr/lib/ruby/gems/1.8/gems directory now holds the following packages:

drwxr-xr-x  4 root root 4096 2008-07-02 12:32 actionmailer-2.0.2
drwxr-xr-x  4 root root 4096 2008-07-02 12:32 actionpack-2.0.2
drwxr-xr-x  5 root root 4096 2008-07-02 12:32 activerecord-2.0.2
drwxr-xr-x  4 root root 4096 2008-07-02 12:32 activeresource-2.0.2
drwxr-xr-x  3 root root 4096 2008-07-02 12:32 activesupport-2.0.2
drwxr-xr-x  4 root root 4096 2008-07-02 13:35 cgi_multipart_eof_fix-2.3
drwxr-xr-x  5 root root 4096 2008-07-02 13:35 daemons-1.0.7
drwxr-xr-x  5 root root 4096 2008-07-02 13:35 fastthread-1.0
drwxr-xr-x  8 root root 4096 2008-07-02 13:35 gem_plugin-0.2.2
drwxr-xr-x  8 root root 4096 2008-07-02 13:35 mongrel-1.0.1
drwxr-xr-x 11 root root 4096 2008-07-02 12:32 rails-2.0.2
drwxr-xr-x  6 root root 4096 2008-07-02 12:32 rake-0.8.1
drwxr-xr-x  3 root root 4096 2008-07-02 12:32 sources-0.0.1

What about lighttpd and fastcgi?

I'll give it to you straight out, right up front. I cannot make lighttpd and fastcgi work any longer. This seemed to break as of lighttpd 1.4.19 and for the life of me I cannot sort it out. Perhaps this is just as well, since the rest of the world seems to have moved on to doing things with mongrel (or a mongrel cluster); and I have learned over the years that it is always prudent to "move with the bandwagon".

The following section in blue just leads to a dead-end with fastcgi, so you probably want to skip it and move along to the next section on lighttpd and mongrel.

Supposedly you can use apache and a mongrel cluster in lieu of this, but my experience thus far has been great with lighttpd and fastcgi. This will let me run a "real webserver" on port 80, rather than postponing that till final deployment.

I do yum install lighttpd-fastcgi (since this handily also pulls in lighttpd itself as a dependency. I get the following packages:

Installing:
 lighttpd-fastcgi        x86_64     1.4.19-4.fc8     updates            46 k
Installing for dependencies:
 lighttpd                x86_64     1.4.19-4.fc8     updates           374 k
 lua                     x86_64     5.1.3-6.fc8      updates           227 k
I don't have a clue what lua is. (A google search tells me that it is a "lightweight extension language", so it is apparently something the lighttpd developers have now embedded in lighttpd. I don't see this pull in the lighttpd-mod_mysql_vhost package (which I do see getting pulled in on my other hosts that already had mysql installed). Maybe you only get this if you have both lighttpd and mysql, or else it is something I will be tripping over later -- or sooner.

I do service lighttpd start and whammo! I am serving up a lighttpd greeting banner on http://localhost. Now lets hack on the config file and see if we can get this to serve up our rails stuff via the fastcgi arrangement. One thing I am nervous about. This is now using lighttpd 1.4.19, and I know this broke my rails setup on another server, this is either my chance to fall into the same hole, or to fix my setup to work with 1.4.19.

I add/change the following lines in /etc/lighttpd/lighttpd.conf:

First, I enable (uncomment) some modules:

mod_rewrite
mod_fastcgi

Then I set some things so it can find my rails directory.

server.document-root       = "/u1/rails/demo"
server.errorlog            = "/u1/rails/demo/log/server.log"
server.error-handler-404 = "/dispatch.fcgi"
Then I add the all-important handoff to fastcgi:
url.rewrite              = ( "^/$" => "index.html", "^/([^.]+)$" => "$1.html" )

fastcgi.server = ( "/dispatch.fcgi" =>
       ((
           "min-procs" => 4,
           "max-procs" => 10,
           "socket" => "/tmp/rails.demo.socket",
           "bin-path" => "/u1/rails/demo/public/dispatch.fcgi",
           "bin-environment" => ( "RAILS_ENV" => "development" )
         ))
)

I restart lighttpd, and now I get a 404 error.

This link to FastCGI troubleshooting may be helpful.

What I do is to turn on some lighttpd debug variables (there are lots of them, and some for each module).

fastcgi.debug = 1
debug.log-request-handling = "enable"

After this change (and restarting the server), a lot more stuff shows up in /u1/rails/demo/log/server.log and a quick perusal of what is there leads me to make this change:

server.error-handler-404 = "/public/dispatch.fcgi"

After about half a day of fussing with this, I am pasting the sticker of doom on this one and concluding that the answer here is:

yum erase lighttpd-fastcgi

After that I played around with a lighttpd and mongrel combination. That was equally disfunctional! Lighttpd can't even manage a proxy handoff to a happy mongrel running on port 3000!! Some of my googling around clued me in that there are "issues" with the mod_proxy component of lighttpd. In particular it is said to lock up when the thing being proxied to fails in some way, and has trouble load balancing. The fact that it just doesn't work is pretty much final for me though.

I am pasting the sticker of doom on lighttpd overall, and moving on to greener pastures. It treated me good for 2 years or so, then turned ugly.
I kiss it goodbye via:

yum erase lighttpd

Bear in mind that I have a server running Fedora Core 8, lighttpd (version 1.4.18) and rails, but I cannot reproduce that setup with 1.4.19 from a fresh Fedora install using yum packages. I will count myself lucky and migrate to apache as quickly as possible.

OK, how about apache and mongrel?

Well, we have already seem mongrel fire up and work on port 3000. The game now is to get this to work on port 80, since "if you ain't on port 80, you ain't nobody".

It turns out this is just dog-easy and it works too! (Always a highly desirable fringe benefit).

I already have apache (aka httpd) as part of my vanilla Fedora Core 8 install, so I just add the following lines to /etc/httpd/conf/httpd.conf and start apache via service httpd start

ProxyRequests Off
ProxyPreserveHost On
<:Proxy *>
        Order deny,allow
        Allow from all
<:/Proxy>
ProxyPass / http://0.0.0.0:3000/
ProxyPassReverse / http://0.0.0.0:3000/
After this, I point a browser at http://localhost and Presto! I am looking at the rails greeting page.

It would be nice to install the mongrel_cluster gem at this point, however this is not available via a yum package, and installing it via gem install mongrel_cluster does not work. The main thing I want from this package is the script that goes into /etc/rc.d/init.d so I can do chkconfig mongrel_cluster on and just forget about this and have it fire up whenever the system boots and use the service command to dork with it.

Fun with ruby gems

I have already been warned that trying to maintain ruby gems via both yum packages and the gem system is fraught with peril. I am already deep into this mess, and I would leave well enough alone, except that I really want the mongrel_cluster gem.

By the way, the following two gem commands give useful information:

I have mongrel 1.0.1 (via yum), but gem has a much newer version (1.1.5), so I get brave and try:

gem update mongrel
This fails complaining that it cannot find the header files for ruby, so I (having been down this road before) do this:
yum install ruby-devel
After this, gem update mongrel does work, and pulls in two dependencies (fastthread and cgi_multipart_eof_fix) as well.
After this, getting the mongrel_cluster gem is like so:
 gem install mongrel_cluster
 Successfully installed mongrel_cluster-1.0.5

Apache and a mongrel cluster

First, we need to get set up to run a cluster: The following steps were abstracted from Using Mongrel Cluster
su
adduser -r mongrel
cd /u1/rails/demo
mongrel_rails cluster::configure -e development -p 8000 -N 2 -c /u1/rails/demo -a 127.0.0.1 --user mongrel --group mongrel 
mkdir /etc/mongrel_cluster
cd /etc/mongrel_cluster
ln -s /u1/rails/demo/config/mongrel_cluster.yml
cd /etc/init.d
cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster .
chmod a+x mongrel_cluster 
Note that we are running the cluster on port 8000 now instead of 3000 (so we will need to change the proxy stuff in /etc/httpd/conf/httpd.conf). Also we have a choice, we can start the cluster via service mongrel_cluster restart, or by hand via:
cd /u1/rails/demo
mongrel_rails cluster::start
Just mongrel_rails start will start a single mongrel (and still on port 3000!)
Feedback? Questions? Drop me a line!

Ruby on Rails notes / tom@mmto.org