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