Rails with Passenger on Open Solaris and EC2

You can now run Sun’s Open Solaris images on EC2 without signing up for their beta program. The newly released “web stack” AMI includes Open Solaris 2008.11, Apache, MySQL and PHP:

Open Solaris 2008.11 + AMP
32-bit AMI: ami-c7cf28ae

The bad news is that there’s still some work to do if you want to run Ruby on Rails. The good news is that the most recent releases of Ruby on Rails (2.3) and Phusion Passenger (2.1.3) include patches that make it much easier to run on Open Solaris. There’s still some work to do and this article aims to give you all the steps needed.

My notes assume you have some experience with EC2, Open Solaris (or at least some Unix/Linux variant) and Rails. Please leave a comment below if anything is unclear.

This article was written using:

  • Ruby on Rails 2.3
  • Passenger Phusion 2.1.3
  • Open Solaris 2008.11

Installing basic GNU tools

We’ll want to go ahead and install gmake, gcc, svn and git. We need to compile the last one from source. As this is the only package we’re installing this way, I just install it directly into /usr. If you feel this is blasphemy of some sort, feel free to install it into your favorite local directory by adding a parameter such as prefix=/opt/local to the configure step.

Steps:

  • install gmake
  • install gcc
  • install subversion
  • install git

Commands:

 $ pfexec pkg install SUNWgmake
 $ pfexec pkg install SUNWgcc
 $ pfexec pkg install SUNWsvn
 $ mkdir -p /opt/src
 $ cd /opt/src
 $ wget http://kernel.org/pub/software/scm/git/git-1.6.2.2.tar.gz
 $ tar xzf git-1.6.2.2.tar.gz
 $ cd git-1.6.2.2
 $ ./configure [--prefix=/opt/local]
 $ gmake
 $ pfexec make install
 $ git --version

Installing Ruby on Rails

Ruby 1.8.6 is already installed with Sun’s AMP stack. However, we need to upgrade ruby gems and apply a few patches.

Steps:

  • update rubygems
  • add github gem server (may not be needed depending on what gems you use)
  • install rails
  • Modify path. Should put this in your profile somewhere.

Commands:

 $ gem update --version
 $ gem sources -a http://gems.github.com
 $ gem install rails
 $ PATH=/usr/ruby/1.8/bin:$PATH

If we want to install gems with native code, we’ll need to update our rbconfig.rb file. Luckily Prashant Srinivasan has made it simple for us.

 $ wget http://blogs.sun.com/prashant/resource/gcc/rbconfig.rb
 $ mv /usr/ruby/1.8/lib/ruby/1.8/i386-solaris2.11/rbconfig.rb /usr/ruby/1.8/lib/ruby/1.8/i386-solaris2.11/rbconfig.rb.original
 $ mv rbconfig.rb /usr/ruby/1.8/lib/ruby/1.8/i386-solaris2.11/rbconfig.rb

We can now install the database gems

 $ gem install mysql -- --with-mysql-dir=/usr/mysql/5.0
 $ gem install sqlite3-ruby

We also need to fix an issue with iconv that requires us to both install the gnu version and change how we link to that library. Details are on the Rubaidh blog and a ticket is open in the Rails bug tracker.

 $ pfexec pkg install SUNWgnu-libiconv
 $ pfexec crle -u -E LD_PRELOAD=/usr/gnu/lib/preloadable_libiconv.so
 $ pfexec crle -s /lib/secure -s /usr/lib/secure -s /usr/gnu/lib

If you don’t like this method of updating your LD_PRELOAD parameter, you can configure Phusion Passenger with custom environmental variables. This is a useful way to handle any path issues you bump into.

Installing Phusion Passenger (mod_rails)

To install Passenger, we first need to install fastthread. Unfortunately, the lastest gem has issues on Open Solaris, so we’ll install version 1.0.1. After that, we can proceed with installing passenger.

 $ gem install fastthread --version 1.0.1
 $ gem install passenger
 $ passenger-install-apache2-module

Now you need to update your Apache httpd configuration:

 $ PASSENGER_CONF=/etc/apache2/2.2/conf.d/passenger.conf 
 $ echo "LoadModule passenger_module \ 
 $    /usr/ruby/1.8/lib/ruby/gems/1.8/gems/passenger-2.1.3/ext/apache2/mod_passenger.so"  \
      > $PASSENGER_CONF
 $ echo "PassengerRoot /usr/ruby/1.8/lib/ruby/gems/1.8/gems/passenger-2.1.3" >> $PASSENGER_CONF
 $ echo "PassengerRuby /usr/ruby/1.8/bin/ruby"  >> $PASSENGER_CONF

Testing

Let’s create a simple rails app using the new Rails 2.3 templates:

 $ mkdir /var/apache2/2.2/apps
 $ cd /var/apache2/2.2/apps
 $ rails blog
 $ cd blog
 $ ./script/generate controller welcome index
 $ chown -R webservd:webservd /var/apache2/2.2/apps

Now we add the virtual host information for passenger:

  $ vi /etc/apache2/2.2/conf.d/vhosts.conf

    <VirtualHost *:80>
     ServerName [YOUR-EC2-DNS-HERE]
     DocumentRoot /var/apache2/2.2/apps/blog/public

     <Directory /var/apache2/2.2/apps/blog>
      Options +FollowSymLinks -SymLinksIfOwnerMatch +MultiViews -Indexes -ExecCGI
      AllowOverride ALL
      Order allow,deny
      Allow from all
     </Directory>

    </VirtualHost>

Now we restart apache:

   $ svcadm restart http:apache22

And we should be able to view our new rails app by going to the public address for our EC2 server. To confirm rails is actually configured correctly, visit /welcome and you should see something like:

Welcome#index

Find me in app/views/welcome/index.html.erb

I’ll leave setting up Capistrano as an exercise for the reader. I’m going to do some more testing with this setup and I may release a Chef configuration for it or my own custom AMIs if there’s interest.