2010-03-01

Install Ruby on Rails, Gem and Passenger on Apache on Ubuntu Karmic

Hi,

I wanted to install ruby on rails on my laptop for development purposes. So after finding several resources (see 'chapter IX') I combined what I had to get my system up and running.

In the meantime I played around with RVM though and to purely develop RoR apps I would not use anything else than the RVM approach so far. I will add a new article about the RVM install as soon as possible, but that even is so straight forward, that you could easily follow the installation procedures from the rvm and the rails 3 sites.

Well now to this article and my environment for which I wrote it:
This howto is written for my laptop at work. Its a Dell Latitude D830 Laptop, running a default Ubuntu Karmic Koala (9.10) (Locales set to GERMAN/GERMANY).My workflow basically looks like:
  • work on the code and apply changes/enhancements
  • commit/push the changes to a Mercurial Repository
  • test the changes locally
  • push the changes to the deployment environment, which automatically migrates and updates itself (I will address this topic in my next howto)
  • enjoy the updated production environment
So here is what I usually do to setup my development envionment. Be aware that these instructions will probably only work in an environment like the one I wrote this Howto for. So if you use another Linux, you might have to do things differently, like use different installers, have a different approach to configure apache, etc... Feel free to adapt this howto to your environment and add a comment stating what you had to do differently on your system (including a system description of course).


I. Install RUBY

First thing to do before I install new things is to update my system, so there we go
sudo apt-get update
sudo apt-get upgrade
    In case you get warnings about your locale, just set em right in accordance to your needs, I didn't have any trouble. But if you wanted to set your environment to US english you'd do it like this:
    sudo locale-gen en_US.UTF-8
    sudo /usr/sbin/update-locale LANG=en_US.UTF-8
      Now, before we are going to install ruby, think about which database you will be going to use for your Ruby-Application. I usually like postgresql or if its for local apps i'd vote for sqlite3. But you might also be fond of or used to MySql. So here are 2 options for the default ruby installation including everything (apt-point of view) you need to connect to your favourite database. So either go

      with a MySql co-installation 
      sudo apt-get install ruby ri rdoc mysql-server libmysql-ruby ruby1.8-dev irb1.8 libdbd-mysql-perl libdbi-perl libmysql-ruby1.8 libmysqlclient15off libnet-daemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 mysql-client-5.1 mysql-common mysql-server-5.1 rdoc1.8 ri1.8 ruby1.8 irb libopenssl-ruby libopenssl-ruby1.8 libhtml-template-perl mysql-server-core-5.1 libmysqlclient16 libreadline5 psmisc 
      or a PostgreSql co-installation
      sudo apt-get install ruby ri rdoc ruby1.8-dev irb1.8 libdbi-perl  libnet-daemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 rdoc1.8 ri1.8 ruby1.8 irb libopenssl-ruby libopenssl-ruby1.8 libhtml-template-perl libreadline5 psmisc postgresql-8.3 postgresql-8.3-plruby libpq-dev
      Of course after the database stuff is installed you should go and setup your database management system, i. e. setup your admin access, your roles, databases and secure the general access to your database system.

      Now check if the installation also included the non-versioned symlinks to the executable files. Type:
      ruby -v
        and if your system does not respond with something like
        ruby 1.8.7 (2010-01-10 patchlevel 249) [i686-linux]
        then you can set the symlinks yourself using:
        sudo ln -s /usr/bin/ruby1.8 /usr/local/bin/ruby
        sudo ln -s /usr/bin/rdoc1.8 /usr/local/bin/rdoc
        sudo ln -s /usr/bin/ri1.8 /usr/local/bin/ri
        sudo ln -s /usr/bin/irb1.8 /usr/local/bin/irb
          where you might have to change the version identifiers in accordance to the ruby version you use.


          II. Install GEMS

          Check http://rubyforge.org/ for the latest version of "rubygems". Then you can install that using
          wget http://rubyforge.org/frs/download.php/<check online for latest version...>
          tar -xvzf rubygems-.tgz
          cd rubygems-
          sudo ruby setup.rb
            For gem too we want to check if the symlink exists
            gem -v
              and gem usually just returns the version info, e. g.
              1.3.5
              If it does not, just create the symlink for gem like you might have done before for ruby & co.
              sudo ln -s /usr/bin/gem1.8 /usr/local/bin/gem

                 III: Install Rails

                Should be easy and not cause any trouble:
                sudo gem install rails
                  At this point you can continue to install all gems you might be interested in. Some gems I usually install because I just like to have them for form building and database connectivitym, are:
                  • formtastic,  justinfrench-formtastic => great form builder
                  • sqlite3 => for developping local apps
                  • RedCloth => for Wiki-like text formatting support (*xxx* => xxx)
                  • ruby-oci8 => connect to Oracle Databases using OCI8
                  • activerecord-oracle_enhanced-adapter => activerecord plugin to connect to Oracle Database
                  • ruby-pg => connect to postgres databases and/or
                  • mysql-ruby => connect to mysql databases
                  At this point you can stop working this howto, in case you only want to develop on your machine. 

                  But if you want to install deployment too... even if only for deployment testing... here is how you may go on:

                    IV. Install Phusion Passenger to deploy apps to production

                     Agreed, there are many ways to do the "deployment"-part of RoR applications right. Personally, I develop not only in Ruby, I also work occasionally on several C/C++, Java and PHP projects. Because most of the projects I participate in use Mercurial RCS, I got very fond of that lovely tool and therefore here I want to explain what I do to develop and safe my applications using the Mercurial RCS to take care of my code versioning and having Phusion Passenger to collaborate with Apache to deploy my applications "on the fly" when I update my versioning repositories.

                    So to get passenger up and running for production, i first install some background stuff to avoid later dependency troubles:
                    sudo apt-get install libc6 libpcre3 libpcre3-dev libpcrecpp0 libssl0.9.8 libssl-dev zlib1g zlib1g-dev lsb-base
                     and then we install the passenger gem
                    sudo gem install passenger
                    At this point you could call the installation script for passenger (see next step), but on a default ubuntu installation it will probably fail because of a few missing dependencies.Trying does not really hurt, because the installation script will tell you what is missing and name the packages you have to install first. Or you can just do the following install to preempt this problem:
                    sudo apt-get install apache2-prefork-dev libapr1-dev libaprutil1-dev
                    Now we call the passenger installation script:
                    sudo passenger-install-apache2-module

                    V. Configure Phusion Passenger <-> Apache Collaboration

                    We can easily configure Apache to use the passenger module for ruby applications. To do so just (be aware that you might install the software with other versions, so be sure to adapt the version identifiers for your apache configuration)
                    sudo echo 'LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so' >> /etc/apache2/mods-available/passenger.load
                    sudo echo 'PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9' >> /etc/apache2/mods-available/passenger.conf
                    sudo echo 'PassengerRuby /usr/bin/passenger_ruby_wrapper' >> /etc/apache2/mods-available/passenger.conf
                    And with that last command here you might think "Huh! What is this wrapper stuff doing there ?!?!". It is a pretty common technique to wrap the actual ruby command by a wrapper shell-script in order to load/set environment variables for the passenger configuration to start, because passenger does not access your systems environment variables. The wrapper script would look like
                    #!/bin/sh
                    #Add your environment variables before the exec line, e.g.
                    #export LD_LIBRARY_PATH=/opt/oracle/instantclient_*_*
                    #export NLS_LANG=GERMAN_GERMANY.UTF8
                    #both of which are pretty useful when you want your app to talk to an oracle database
                    exec "/usr/bin/ruby" "$@"
                    Now you can enable the plugin by
                    sudo a2enmod passenger
                    and restarting your apache2 installation by
                    sudo /etc/init.d/apache2 restart

                    VI. Deploy your Rails applications

                    My way to do this on a machine is to create a new user... like 'rails', then I set this users password to something pretty fuzzy, followed by copying my default users public ssh-key to the new users .ssh/authorized_keys... Well thats my way of beeing lazy. I agree I would not actually need to do this as I could do all further commands using sudo... but in my next article I will write about deployment on a remote machine and then this procedure comes in very handy.

                    So to get our applications up and running, I create a 2 new directories in that users home directory.
                    mkdir /home/rails/sources
                    which is the directory where I put copies of my rails application directories, and
                    mkdir /home/rails/apps
                    in which I create symlinks that point to the 'public' directory of the according application directory in the sources tree.

                    So lets say I developed an application called 'moviemng'. To get it deployed, I would
                    sudo cp -r moviemng /home/rails/sources
                    sudo ln -s /home/rails/sources/moviemng/public /home/rails/apps/moviemng
                    No more configuration needed. Just add the symlink to the apache vhost configuration (as described in the following section).


                    VII. Create one apache VHost for all your rails-apps

                    One nice thing about passenger is, that you can have multiple apps accessible by one vhost. That of course would also leave you with the option to create multiple vhosts with one app or even a collection of apps each...

                    A passenger vhost would have the following content (again I use my way, i. e. user rails deploys the production environment in his home directory)

                    <VirtualHost *:80>

                      ServerName www.yourhost.com

                      DocumentRoot /home/rails/apps

                      # Name the symlinks from the
                      # DocumentRoots point of view
                      # to your apps here
                      RailsBaseURI /moviemng

                      <Directory /home/rails/apps>

                        # v-- relax Apache security settings
                        AllowOverride all

                        # v-- MultiViews must be turned off
                        Options -MultiViews

                      </Directory>

                    </VirtualHost>

                    So to add another application 'testapp', of which you have dropped its directory in the '/home/rails/sources' directory and for which you have created a new symlink 'testapp' in '/home/rails/apps' pointing to '/home/rails/sources/testapp/public' you just have to add another
                    RailsBaseURI /testapp
                    and restart your apache
                    sudo /etc/init.d/apache2 restart


                    VIII. Conclusion:


                    From this point on you should have fun working on your rails app while also beeing able to (maybe temporarily, maybe not) deploy your apps locally.
                    This deployment technique also works for remote servers. I will write another howto soon that will cover whats needed to know for that.



                    IX. Sources

                     http://www.hackido.com/2009/11/install-ruby-on-rails-on-ubuntu-karmic.html
                    acually the base source for this article. 'Hackido' has a good collection of lovely howtos for many different things, among which you will find not only ruby, rails and ubuntu information but also mobile stuff and other linux related howtos

                    http://dague.net/2008/05/19/perfect-rails-development-deployment-environment-with-mercurial-and-passenger/
                    this article from Sean had great influence in my final decision to do the whole deployment-stuff with mercurial and phusion passenger. His tag cloud covers a lot of topic of which there for sure are several that might be interesting for the average coding or just purely funhaving internet surfer. I will soon dedicate an article where I will describe this post of Seans set up in my environment.
                    http://www.modrails.com/
                    where Phusion Passenger comes from, good documentation
                    http://ubuntuforums.org/
                    always a great place to start collecting ideas to get your problems solved