Installing Phusion Passenger on CentOS 5.5

Need to run Rails apps under Apache?  Phusion’s Passenger is becoming the de-facto standard for doing so with its ease of setup, low memory footprint, and deep support.  Once you have Ruby and Rails setup on your CentOS server (see this post), you can install Passenger and integrate it with Apache.  Here’s how:

1) Install the Apache development tools
Passenger is nothing more than a dynamic shared object (DSO).  You will need the httpd-devel package to build Dynamic Shared Objects (DSOs) for Apache.  The following command will install it:

yum install httpd-devel

Depending on your server, you will notice a number of dependent packages being installed, including apr-devel, perl, and apr-util-devel.

2) Install Passenger.
Passenger is a gem, and installed in the typical fashion of any gem:

gem install passenger
Building native extensions.  This could take a while...
Building native extensions.  This could take a while...
Successfully installed fastthread-1.0.7
Successfully installed passenger-2.2.15
2 gems installed
Installing ri documentation for fastthread-1.0.7...
Installing ri documentation for passenger-2.2.15...
Installing RDoc documentation for fastthread-1.0.7...
Installing RDoc documentation for passenger-2.2.15...

3) Build Passenger for Apache
Passenger has a scripted installer. Start it with this command:


The first thing it will do is check its own dependencies. If you have everything in place, you will see this:

Follow the onscreen keyboard prompts from the script, and you will see build messages scroll quickly by as the binaries are built. If the build is successful, you will be presented with this final screen before the shell script exits:

4) Integrate Passenger with Apache
Before beginning, make a copy of your Apache httpd.conf file:

cp /etc/httpd/conf/httpd.conf httpd.conf.orig

Then edit the httpd.conf file and search for the LoadModules section. Add a directive at the end of this list to load the Passenger shared object. It should look like this:

Now scroll down to the end of the file, and add these lines to help the Passenger shared object find the ruby and gem binaries:

PassengerRoot /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.15
PassengerRuby /usr/local/bin/ruby

5) Add a symlink to your app
Change to the directory specified by the server-wide DocumentRoot directive (/var/www/html) and add a symlink to your Rails application. In this case, our Rails application lives in the /webapps/todos directory, so the symlink should link to the “public” directory of the application:

ln -s /webapps/todos/public/ todos

6) Add a virtual host directive for your Rails application
Point Apache to your Rails application:

    ServerName localhost
    DocumentRoot /var/www/html
    RailsEnv development
        Allow from all
        Options -MultiViews
     RailsBaseURI /todos

Now restart Apache with an “apachectl restart” command, and browse to your Rails app.  That’s it!

AirTran's missed technology opportunities

Let me start by saying that I love AirTran as an airline.  On a recent trip from Atlanta to New Orleans, my flight arrived early in BOTH directions.  Not an easy feat, and certainly a reason they are currently atop the annual Airline Quality Ratings published by the U.S. Department of Transportation.

Like most airlines, AirTran sends timely email notifications of special fares, and offers the ability to check-in online or at a kiosk.  When I went to check-in at a New Orleans airport kiosk, I encountered a problem that prevented me from printing my boarding pass.  After two tries, the kiosk finished by spitting out this piece of paper:

I have received a “Counter Assistance Ticket” from the kiosk.  What do you see that’s broken here?  Here’s what I see:

1)  The first sentence tells me what to do with the ticket; take it to a counter agent to help finish my check-in.  OK, I can accept that some people might need explicit instructions, so we can let this part go.

2) I take my ticket to the counter, and hand it to the customer service agent.  I proudly state that I have a “hostfail” with a reference number of NGDMJE, and hand it to her.  She takes the ticket from me, opens up a three-ring binder on her counter, and cross-references the error.

Except that didn’t happen.

She is a customer service representative, not an engineer, and has no idea what “hostfail” means.  She cannot use the ticket to help me.  Instead, she starts fresh by asking for my last name and destination.

Its clear that this error was recorded on some internal AirTran system with a reference number that could be used to directly reference (and presumably fix) it. So the ticket doesn’t help her and it doesn’t help me.  Why print it at all?  Why complicate a process and incur the expense of printing paper?  In an industry with such tight margins, I can only imagine how much money AirTran is throwing away each day with these printings.

2)  getBooking(Pricing) failed.   The security-minded part of me sees that AirTran has now revealed a method from its code, in addition to the likely hostname of the kiosk itself:  MSY-IKSKTKT04.  This is an unnecessary leakage of infrastructure information.

3)  System.OutOfMemoryException also tells me, by its syntax, that this kiosk is probably running on .NET technology. It also tells me that there is a disconnect somewhere in AirTran’s QA function which has enabled a memory leak to surface.

All this bothered me, and I decided to use Twitter to tell AirTran about it.  Many companies use Twitter for customer service functions today, and I expected nothing different.  Here’s what I saw on AirTran’s twitter page:

One tweet.  One.  From almost a full year ago.  And they have accrued 2, 612 followers during that time.  What company would not love to have almost three thousand customers waiting to interact with them?  By contrast, Delta has 744 followers, and has tweeted 58 times.

AirTran has almost four times the amount of followers that Delta has, but doesn’t use them.  Its only tweet was a version of “Hello, world” followed by a year of silence.  This is clearly a missed opportunity for AirTran to connect with its customers.

In the two touches I made to their technology stack, I saw problems AirTran could easily fix to make themselves friendlier and more useful to travelers.  Will they?

7 Steps to Rails on CentOS

Red Hat Linux (and its recompiled cousin, CentOS)  has a fantastic reputation for stability and maturity.  However, this often means that packages included with the OS are somewhat out-of-date by the time the distribution is released.  For example, the latest version of CentOS is 5.5, and the version of Ruby that ships with it is version 1.8.5, which dates back to August 2006.  Even the Ruby group recommends using nothing less than 1.8.7 for Rails development.

So how do you get the stability of Red Hat with the goodness of Ruby? Compile from source to get the latest, greatest version.  Here’s how:

1)  Install CentOS 5.5
To save yourself alot of headaches during the installation, check to see if you have the “Development Tools” group installed with this command:

# yum grouplist |grep -i Development

If you don’t have it, install the package group with this command:

#yum groupinstall "Development Tools"

Note that you may also have the older version of Ruby installed via RPM’s.  You can check to see if you have it with this command:

# rpm -qa |grep ruby

If you discover an older version, uninstall it before proceeding (rpm -e <package_name>).

2) Create a /sources directory and change to that directory.

3) Download and build Ruby.
Download the latest Ruby source code (latest version is 1.9.2-p0 as of this writing).


Uncompress the tarball and build Ruby:

tar -zxvf ruby-1.9.2-p0.tar.gz
cd ruby-1.9.2-p0
make install

If you have all the proper dependencies, you should have no errors during the configure or make phases. This will install Ruby to the following directories:


Once the install is complete, verify the version of Ruby:

# ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036)

The Ruby source package also installs RubyGems, the Ruby package manager.  Verify the version of RubyGems:

# gem -v

4) Check for updated gems
Ensure you have the latest gem versions by running this command:

# gem update --system

5) Install the rake build language

# gem install rake

6) Install rails

# gem install rails

7) List the installed gems.

# gem list

That’s it! You now have a fully-installed Ruby on Rails stack.  However, Ruby also needs a back-end database and a web server for its presentation layer.   Future posts will detail how to install and integrate web server and database tiers with Rails.

SharePoint People & Groups not updating

We recently discovered a problem with user information in the “People and Groups” view of a SharePoint web application not updating. While a user’s MySite was accurately updated with a photograph, an “About me” section, and profile information, the same user in a web application People and Groups view was not updated. This updating is typically handled via the Quick Profile Synchronization timer job.

To test the problem, we tried altering a user’s photograph and “About me” text and waited an hour for the timer job to fire. Nothing changed. It appeared that the timer job did not have access to update the view, and nothing was logged to the Event or ULS logs about the problem. Here is how we fixed it:

Open Central Administration, then browse to Application Management/Content Databases and select the web application which is experiencing the problem. Ensure all of the content databases are in the “Started” state; if a database is in the “Stopped” state, the timer job will be blocked from updating the database. As you can see in the screen capture below, several of our databases were in the “Stopped” state:

The next step was to temporarily set the Quick Profile Synchronization timer job to run every 2 minutes from its default of every 59 minutes. This timer job synchronizes user information in content databases from user profile data.  Reducing this setting allowed us see that profile synchronization was working without having to wait 59 minutes for the next run.  The command to change the timing is:  stsadm -o sync -synctiming m:2

We then ran the “preparetomove” stsadm command on the database that was not being updated properly. This command temporarily stops the profile and membership synchronization service from running against the database. The syntax for this command is:

stsadm -o preparetomove -contentdb  servernameinstance:content_db_name -site http://your_site_url

After that command completes successfully, detach the database using Central Admin/Content Databases/Manage Content Database Settings. Be sure to write down the name and server location of the database.  After successfully removing the database, reattach it to the web application using the same process, but in reverse.

Once the database is attached, run the “preparetomove” command again, but with the “–undo” flag this time to undo the “preparetomove” operation:

stsadm -o preparetomove -contentdb  servernameinstance:content_db_name -undo -site http://your_site_url

After the command completes successfully, run the following stsadm command to clear all synchronization information: stsadm –o sync –deleteolddatabases 0

After that, simply wait two minutes for the timer job to fire.  Profile information should start syncing up in the People and Groups view.  Here is the view before making the change:

And here is the “after” view; note the updated photograph and “About me” entries that were successfully synchronized:

Remember to reset the Quick Profile Synchronization timer job to run at the default 59 minutes: stsadm -o sync -synctiming m:59


My first install of Ruby on Rails on Linux is now complete.  Would that be RoRoL?

Unlocking the Bank.

The ATM is being serviced, and you are forced to go inside the bank to get cash. You can’t help but marvel at the huge monstrosity of the vault door, swung open during business hours:

Your money isn’t the only thing locked up in that vault. Your data is too.

Look at your current bank.  What can you do with your financial data? You can download it into Quicken to view some pretty reports or review your recent transactions.  Or you could view it on the bank’s own website, where you could transfer money between accounts, setup an alert, or use a bill-pay service to schedule monthly payments.

Or you could connect your account with Mint, where your transactions will be parsed out and categorized for you.  And if you have the extra time, you could tag each transaction into more detailed categories for improved reporting:

But your data is still inert.  Lifeless.  Motionless. And the only entity that has access to it is your bank, who often uses it to cross-sell you insurance, mortgage, loans, and savings accounts.  I know you get those offers in the mail just like I do.

What if that model was turned on its head?  Instead of your data being locked in a vault and being read-only to you, it could be dynamic, movable, and wrapped in a rich set of metadata decorations.

Last week BankSimple revealed that it will be publishing its own API that would let external applications grab that data and do something with it.  Think about that.  What applications could you build on a banking API?

Lets say I eat at Cheesecake Factory once a week and pay with a debit card.  Yet the restaurant knows nothing about me.  They don’t know who I am, how much I spend on each visit, or how often I am there.  But what if they had an application that I permitted secure access my transaction metadata at BankSimple?

Could they automatically take 10% off my check when they ran my card and saw it was me?  Could they send me discount coupons if they noticed I stopped visiting regularly?  A banking API might enable such an application to be built, and I wouldn’t have to remember to carry around another silly reward/membership card!  Wouldn’t that make for a more efficient restaurant loyalty program?

What other applications could you build on a banking API?

Jolicloud: the OS for Grandma?

My mother-in-law lives in a rural home in middle Georgia.  She is 74 and has never used a computer in her life.  When we visit on weekends, we often show her photos on our iPhones.  But somehow that just feels unsatisfying; we wish we could show her full-size versions of our photos, and connect with her via email and instant messenger during the week.

I dug up an old Dell d610 laptop with 1GB of RAM, 100GB hard disk, and a single Pentium mobile processor.  There are not many operating systems made today that can run with such minimal hardware.  I figured a lightweight OS made for the puny hardware of a netbook might fit the bill.  Enter Jolicloud.

Jolicloud is a free, Ubuntu Linux-based OS tweaked for netbooks.  Its user interface is built on the fancy HTML5 standard, and looks gorgeous. Installation is done via a downloadable CDROM, available from the Jolicloud website.  Installation on the Dell took about 30 minutes, and it detected every bit of hardware with no issues.

Once installed, you get a simple black background with large icons and a slim toolbar across the top. Here is what it looks like:

Facebook.  Gmail.  Meebo.  The everyday applications you commonly use, presented in two neat rows.  Would you have any difficulty figuring out this interface?

Now, lets assume you want to access your documents.  Click the folder icon on the top toolbar and get taken to this screen:

Does it get any more intuitive?  You have folders for your documents, music, photos, and videos.  Also notice the inclusion of web-based file storage solutions, neatly presented below your local storage for seamless access.

Or lets say you want to see what this “Twitter” thing is all about, and you want to install a Twitter client.  Click on the “Add” button on the upper left corner of the toolbar, and you can browse installable applications by type. A single click will start the install.  Also notice that currently-installed programs are dimmed to indicate you already have them.

As you can clearly see, my mother-in-law won’t have any problems figuring out how to operate this computer.  And with the stable Linux operating system underneath, I don’t expect to get many support calls either.  Jolicloud is snappy and responsive with only 1GB of RAM, negating the need to purchase a RAM upgrade.  And did I mention Jolicloud is free?

Now if they could only get Internet access…