Defindit Docs and Howto Home

This page last modified: Mar 18 2011
title:Apache httpd Phusion mod_passenger Ruby Rails
keywords:phusion,passenger_module,mod_passenger.so,PassengerRoot,PassengerRuby,LoadModule,apache,httpd,http,gem,ruby,rails,cgi,disable, centos,gem
description:Configuration for the Phusion passenger gem and Apache module with Rails coexisting with normal HTML web pages and Perl CGI. Also some notes about running Ruby on Rails with CentOS 5.


Table of contents
-----------------
Introduction
How to install Ruby Enterprise with CentOS 5
What paths are involved?
Passenger and rvm
How to restart the Rails app under mod_passenger.
Running two Rails applications in a single virtual host



Introduction
------------

These notes cover some details of getting Phusion passenger running
under the Apache httpd server, and still preserving the ability to run
normal HTML web pages and Perl CGI in the same httpd instance.

In order to solve many compatiblibity issues with Ruby and the gems, I
have used rvm since June of 2010. It works well, and I was even able
to install mod_passenger as root relying on my user space rvm
install. In other words, Ruby and related technology was installed as
user mst3k, but mod_passenger was installed by root, and httpd is
started via the typical /etc/init.d/httpd start command.




How to install Ruby Enterprise with CentOS 5
--------------------------------------------

It is much easier to simply run passenger on a separate server. I
prefer Fedora Linux. This section refers to CentOS which is a bit
tricky to work with because all the software is old versions.

The ruby and rails distro that is in the yum repo for Centos 5 does
not work. (See the troubleshooting section below.) I solved the
problem by installing Ruby Enterprise from source. Even with Ruby
Enterprise there are issues with some gems, so certain gems have to
be removed and different versions installed. Happily this is easy.


# Installed as root to be system wide. Given the way Phusion Passenger
# mod_passenger works, you can probably install Ruby Enterprie in user
# space. When working as root, I prefer to "sudo su -l root" one time,
# and then work as user root rather than using sudo for every command.

# You must visit the Ruby Enterprise web site and determine the most
# recent stable version and substitute it as necessary in the commands
# below.

# For this example you are userid "mst3k" on host
# "aims.lib.example.edu" which is a Centos 5 Linux server.

ssh mst3k@aims.lib.example.edu
sudo su -l root
wget http://rubyenterpriseedition.googlecode.com/files/ruby-enterprise-1.8.7-2011.03.tar.gz
tar -xzf ruby-enterprise-1.8.7-2011.03.tar.gz 
./ruby-enterprise-1.8.7-2011.03/installer
/opt/ruby-enterprise-1.8.7-2011.03/bin/passenger-install-apache2-module

# Edit your Apache configuration file, and add various lines in
# appropriate sections. Remember that your passenger config may be
# different. Use the recommended config from the output of the
# passenger install (the previous command).

LoadModule passenger_module /opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.5/ext/apache2/mod_passenger.so
PassengerRoot /opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.5
PassengerRuby /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby

# There are a few other directives you will probably need in httpd.conf

# Comment out the userdir disable in order to enable userdir.

    # UserDir disable

# Assuming you put the Donor Survey and TAPER submission tool in your
# public_html, give yourself full override privileges.

<Directory /home/mst3k/public_html>
    AllowOverride all
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    <Limit GET POST OPTIONS>
        Order allow,deny
        Allow from all
    </Limit>
    <LimitExcept GET POST OPTIONS>
        Order deny,allow
        Deny from all
    </LimitExcept>
</Directory>

NameVirtualHost *:80

<VirtualHost *:80 >
    ServerName aims.lib.example.edu
    # be sure to point to 'public'!
    DocumentRoot /home/mst3k/am_ruby/public
    setenv RailsEnv development
    # Based on config/environment.rb the var is all caps, with underscore
    # This works (but still serves the test instance)
    setenv RAILS_ENV development

    setenv PassengerLogLevel 3
    setenv PassengerUseGlobalQueue on
    setenv RailsFrameworkSpawnerIdleTime 0
    setenv RailsAppSpawnerIdleTime 0

    <Directory /home/mst3k/am_ruby/public >
       # relax Apache security settings
       AllowOverride all
       # MultiViews must be turned off
       Options -MultiViews
       AuthUserFile /home/mst3k/.htpasswd
       AuthGroupFile /dev/null
       AuthName Rubymatica
       AuthType Basic
       require valid-user
    </Directory>
</VirtualHost>

# See below for changes to the local .htaccess. Change .htaccess at
# the end when you are no longer logged in as root.

# Install without docs. I get all my docs on the www. Besides, there
# were errors or warnings when installing the docs.

/opt/ruby-enterprise-1.8.7-2011.03/bin/gem install sqlite3-ruby --version '1.2.5' --no-rdoc --no-ri
/opt/ruby-enterprise-1.8.7-2011.03/bin/gem list
...
sqlite3-ruby (1.2.5)
...

# There is a problem with rails 3.0.5 under Centos. Bad or
# incompatible version of rails, so go with 2.3.11 there was a web
# site with the error that script/server threw.

/opt/ruby-enterprise-1.8.7-2011.03/bin/gem uninstall rails
/opt/ruby-enterprise-1.8.7-2011.03/bin/gem install rails -v'2.3.11'  --no-rdoc --no-ri

# Rubymatica needs nokogiri and bagit.

/opt/ruby-enterprise-1.8.7-2011.03/bin/gem install nokogiri --no-rdoc --no-ri

cd ~/									   
git clone git://github.com/flazz/bagit.git
cd bagit/
/opt/ruby-enterprise-1.8.7-2011.03/bin/gem install bagit validatable --no-rdoc --no-ri

/etc/init.d/httpd restart

exit

cd ~/public_html/min_lims

# Edit or create the .htaccess and put in everything between -- below.
  
emacs .htaccess
--
# Necessary to disable passenger for non-rails directories. 
# Causes an error if passenger is not running, but that's easy enough to fix.

PassengerEnabled off 

Options indexes
DirectoryIndex index.pl

AddHandler cgi-script .pl
Options ExecCGI All
--

Rubymatica:

http://aims.lib.example.edu/

Donor Survey:

http://aims.lib.example.edu/~mst3k/min_lims/

which should redirect to:

http://aims.lib.example.edu/~mst3k/min_lims/login.pl



Troubleshooting
---------------

These suggestions have not been well tested, so your actual commands
may be somewhat different. Several problems were enountered with ruby
from the centos yum repo.

Ruby script/server may give more debugging information that
mod_passenger. You can install ruby, rails, rubygems, and maybe some
other packages via yum. I am unclear about what happens to gems
installed by yum when you run the gem command. The gem command seems
to work.

The yum installed Ruby and associated gems had several issues, but
after getting Ruby Enterprise working, it might be possible to apply
the same fixes and get the standard ruby working as well.

sudo su -l root
yum install ruby rubygem-rake rubygem-rails rubygem-nokogiri 

# Change the standard rails to an older version that works with
# script/server.  You'll need an older version of sqlite3-ruby also.

gem uninstall rails
gem install rails -v'2.3.11' --no-rdoc --no-ri

gem install rubygems-update --no-rdoc --no-ri
update_rubygems
gem install rails passenger sinatra --no-rdoc --no-ri
passenger-install-apache2-module
exit
cd am_ruby
script/server




What paths are involved?
------------------------

Development was:

~/aims_1/am_ruby

Production was:

~/prod_rubymatica

Normal Perl CGI and html (non-Rails) was in:

~/public_html/min_lims

In the examples below, the Rails app is the production
instance. Simply create a new VirtualHost directive with the dev path
in order to run the dev instance.



Passenger and rvm
-----------------

Based on instruction from these web pages:

http://dalibornasevic.com/posts/21-rvm-and-passenger-setup-for-rails-2-and-rails-3-apps

http://www.modrails.com/documentation/Users%20guide%20Apache.html#_installing_upgrading_and_uninstalling_phusion_passenger


su -l root
export APXS=/usr/sbin/apxs
export rvm_path=/home/mst3k/.rvm

# get the rest of the env settings from mst3k

source "/home/mst3k/.rvm/scripts/rvm"

# Just check to see that rvm really is the same as used by mst3k

rvm -v

gem install passenger
passenger-install-apache2-module


# Based on hints given by passenger-install-apache2-module, I added
# the following lines to httpd.conf around line 209, after the other
# LoadModule directives:

LoadModule passenger_module /home/mst3k/.rvm/gems/ruby-1.8.7-head/gems/passenger-3.0.3/ext/apache2/mod_passenger.so
PassengerRoot /home/mst3k/.rvm/gems/ruby-1.8.7-head/gems/passenger-3.0.3
PassengerRuby /home/mst3k/.rvm/wrappers/ruby-1.8.7-head/ruby


# Enable UserDir if you will be serving web pages from
# /home/*/public_html This is not necessarily a part of enabling
# Rails, but since my instructions here are about both Rails and
# normal httpd/cgi, I am including all the details.

<IfModule mod_userdir.c>
    #
    # UserDir is disabled by default since it can confirm the presence
    # of a username on the system (depending on home directory
    # permissions).
    #
    #    UserDir disabled

    #
    # To enable requests to /~user/ to serve the user's public_html
    # directory, remove the "UserDir disabled" line above, and uncomment
    # the following line instead:
    #
    UserDir public_html
</IfModule>

#
# Control access to UserDir directories.  The following is an example
# for a site where these directories are restricted to read-only.
#
<Directory /home/*/public_html>
     AllowOverride All
    DirectoryIndex index.pl index.html
    <Limit GET POST OPTIONS>
        Order allow,deny
        Allow from all
    </Limit>
    <LimitExcept GET POST OPTIONS>
        Order deny,allow
        Deny from all
    </LimitExcept>
</Directory>



# Search httpd.conf for NameVirtualHost, and add a new line below the
# commented out example:

NameVirtualHost zeus.lib.example.edu 

# At the end of the httpd.conf, add the VirtualHost directive. I am
# somewhat confused about RailsEnv and RAILS_ENV. The directive below
# works. 

<VirtualHost zeus.lib.example.edu>
    ServerName zeus.lib.example.edu
    # be sure to point to 'public'!
    DocumentRoot /home/mst3k/prod_rubymatica/public
    setenv RailsEnv development
    # Based on config/environment.rb the var is all caps, with underscore
    # This works (but still serves the test instance)
    setenv RAILS_ENV development

    setenv PassengerLogLevel 3
    setenv PassengerUseGlobalQueue on
    setenv RailsFrameworkSpawnerIdleTime 0
    setenv RailsAppSpawnerIdleTime 0

    <Directory /home/mst3k/prod_rubymatica/public >
       # relax Apache security settings
       AllowOverride all
       # MultiViews must be turned off
       Options -MultiViews
    </Directory>
</VirtualHost>

# exit from root, and go back to being user mst3k.

exit


# In public_html/min_lims/.htaccess necessary to disable passenger for
# non-rails directories.  Causes an error if passenger is not running,
# but that's easy enough to fix.

PassengerEnabled off 

# My full .htaccess is below. I cannot remember why I have Options
# indexes on, nor why I would need Options All. ExecCGI is necessary
# for the Perl scripts, as well as AddHandler. Usually FollowSymLinks
# is necessary (and it probably part of All). I suggest that you
# experiment with the smallest set of Options that will give you a
# working web site. I put a comment in my .htaccess about the
# PassengerEnable since I consider that non-standard for a typical
# html/CGI web site.

# Necessary to disable passenger for non-rails directories. 
# Causes an error if passenger is not running, but that's easy enough to fix.
PassengerEnabled off 
Options indexes
DirectoryIndex index.pl
AddHandler cgi-script .pl
Options ExecCGI All



# Alternatively, you could disable passenger for select directories in
# httpd.conf in the VirtualHost directive.

     <Directory /home/mst3k/public_html/min_lims >
        # relax Apache security settings
        AllowOverride all
        PassengerEnabled off
        DirectoryIndex index.pl
        # MultiViews must be turned off
        Options -MultiViews
     </Directory>




How to restart the Rails app under mod_passenger.
-------------------------------------------------

# The directory aims_1/am_ruby contains public, apps, tmp, and other
# Rails directories for my application.

cd aims_1/am_ruby
touch tmp/restart.txt

# I have a three line shell prompt including the full working
# directory path.

    mst3k@zeus Wed Mar  2 10:28:29 EST 2011
    /home/mst3k/aims_1/am_ruby
> touch tmp/restart.txt 




Running two Rails applications in a single virtual host
-------------------------------------------------------

I tried and sort of succeeded in having both production and
development Rails apps served by the same passenger instance, and
using only one virtual host. It mostly works, but the Rails URLs in
the second application all have to be URL relative, and that can break
things. You will be much happier just creating a second virtual host.

Dev was:

~/aims_1/am_ruby

Prod was:

~/prod_rubymatica


Oddly, the first time I started httpd, URLs that did not end in '/' gave
an error. I'm not sure how I accidentally fixed this issue. It may
have been by adding the following directive to my httpd.conf:

NameVirtualHost zeus.lib.example.edu 

# worked:

http://zeus.lib.example.edu/dev/

# broken (but eventually worked):

http://zeus.lib.example.edu/dev 

# After I got everything working, *both* URLS above worked, but I'm
# still not sure how I fixed that.


<VirtualHost zeus.lib.example.edu>
    ServerName zeus.lib.example.edu
    # be sure to point to 'public'!
    DocumentRoot /home/mst3k/prod_rubymatica/public
    setenv RailsEnv development
    # Based on config/environment.rb the var is all caps, with underscore
    # This works (but still serves the test instance)
    setenv RAILS_ENV development

    setenv PassengerLogLevel 3
    setenv PassengerUseGlobalQueue on
    setenv RailsFrameworkSpawnerIdleTime 0
    setenv RailsAppSpawnerIdleTime 0

    <Directory /home/mst3k/prod_rubymatica/public >
       # relax Apache security settings
       AllowOverride all
       # MultiViews must be turned off
       Options -MultiViews
    </Directory>

    # The lines below were for an experiment to run two Rails apps in
    # one virtual host. I do not recommend this.

    RailsBaseURI /dev
    <Directory /home/mst3k/prod_rubymatica/public/dev >
        Options -MultiViews
    </Directory>

</VirtualHost>


# Absolute URLs break regardless. What is the note about rest-ful behavior?

http://www.modrails.com/documentation/Users%20guide%20Apache.html#sub_uri_deployment_uri_fix

# symlink the second rails app to a subdir in first apps's
# public. Note: I have cd'd to the public dir of my second Rails app,
# so I am using the short-cut version of "ln -s" that does not have
# the second path (because the second path is implied as ./).

    mst3k@zeus Wed Mar  2 12:59:57 EST 2011
    /home/mst3k/prod_rubymatica/public
> ln -s /home/mst3k/aims_1/am_ruby/public dev


# These are the config lines to original vhost directive for the experiment.

    RailsBaseURI /dev
    <Directory /home/mst3k/prod_rubymatica/public/dev >
        Options -MultiViews
    </Directory>

# Restart second rails app via the normal second app's restart (as
# opposed to using the first app's restart, or some variation with the
# first app).

    mst3k@zeus Wed Mar  2 13:02:23 EST 2011
    /home/mst3k/prod_rubymatica
> touch ~/aims_1/am_ruby/tmp/restart.txt