cPanel + Ruby on Rails + Phusion Passenger

Overview

What does this guide cover?

This guide will demonstrate how to install and run Ruby, Ruby on Rails, and Phusion Passenger on a cPanel server running CentOS.

Benefits

The tools provided by cPanel to manage Ruby on Rails apps are not yet compatible with Rails 3. Passenger helps solve this problem because it is able to serve both Rails 2 and 3 apps out of the box. Configuration is relatively since Passenger does not require the use of rewrites to map sites to a high-numbered port (unlike the configuration described in this article, cPanel assigns each rails app to a mongrel server process that runs on a port greater than 12000). In its simplest form, a Passenger-enabled site only requires that the “DocumentRoot” variable be changed inside its VirtualHost entry.

Caveats

When using passenger, the rails utility in cPanel must be abandoned as it will no longer function correctly. Starting and stopping apps running under passenger is performed in a way that is incompatible with this utility and the ‘Manage Rewrites’ section of the cPanel rails utility is rendered unnecessary since passenger does not require mapping apps to specific ports. Also, if Rails 3 is installed, the “create app” functionality will no longer work. Therefore, it is highly recommended that the “Ruby on Rails” utility be completely disabled server-wide.

Steps covered in this guide

Install ruby

Install passenger

Enable passenger module in apache

Customize rails app to work with passenger

Assumptions

This guide assumes that you are familiar with linux and are comfortable working on the command line.

Supplemental resources

This guide contains all the required information for installing Ruby, Ruby on Rails and Phusion Passenger, but the following resources are directly related and may prove to be helpful.

Changes within VirtualHost directive

Installing Ruby and Ruby on Rails

Procedure

Step 1: Install Ruby on Rails

Run installation script provided by cPanel (installs ruby 1.8.7, see below for installing other versions of ruby with RVM)

cPanel provides a script that will first install ruby on the server. This script will then install the necessary ruby gems (modules) that are necessary to get rails apps working. Type the following command to run this script:

/scripts/installruby

This script installs ruby 1.8.7, rails 2.3.x and related gems.

Alternative: Install a different version of ruby using RVM

cPanel installs ruby 1.8.7. However, it is possible to install a different version of ruby. The best way to do this is probably to use Ruby Version Manager (RVM), which allows you to install additional versions of ruby without interfering with the server’s main installation. Therefore, you can install ruby using cPanel’s script as described above and later install another version of ruby using rvm without fear of overwriting anything. See this article for more details about Installing rubies using rvm.

Step 2: Install Phusion Passenger

Install passenger gem

After ruby is installed, you can install the passenger gem easily. As root, run the following command:

gem install passenger

Compile and install mod_passenger

In order for rails apps to be served by apache, the passenger module must be compiled and installed.

Just to be extra sure that passenger will be able to find the path to apache’s apxs tool (which is used to compile apache modules from source), you should explicitly define the APXS2 environment variable. cPanel’s version of apache installs this binary to /usr/local/apache/bin/apxs, so you would set the APXS2 variable like so:

export APXS2=/usr/local/apache/bin/apxs

Next, run the following command to build and install the module (the exact path may differ slightly depending on the version of passenger that was installed):

Please edit your Apache configuration file, and add these lines:

PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.15

PassengerRuby /usr/bin/ruby

You will need the configuration directives that are printed out for you in the next step.

Step 3: Enable passenger module in apache

Place configuration options in cPanel-provided include file

Before it will work, the passenger module must be enabled in your apache configuration. This simply consists of copying the directives printed out for you in step 2 and pasting them into the appropriate apache configuration file. However, you cannot simply modify the main httpd.conf file located at /usr/local/apache/conf/httpd.conf because cPanel regularly rebuilds this file and your modifications will be lost. Instead, you should add the directives to the appropriate include files that cPanel provides, which are automatically included into the master configuration file.

In this case, the file that you want to use is /usr/local/apache/conf/includes/pre_main_2.conf. Open the file in an editor and add the following lines:

PassengerRuby /usr/bin/ruby

/scripts/restartsrv_httpd

Step 4: Customize rails app to work with passenger

Create custom include file for domain

The path to your rails apps are almost certainly going to be somewhere other than the default document root that is configured automatically by cPanel. Therefore, for each domain that corresponds to a rails app, it is necessary to override the DocumentRoot directive inside its VirtualHost block. Again, it is not possible to make permanent changes simply by editing /usr/local/apache/conf/httpd.conf, since these will be overwritten the next time the apache configuration file is rebuilt. The correct way to override directives inside a site’s VirtualHost block is to use custom include files. In addition to following this guide, I encourage you to read through cPanel’s online documentation on this subject. This will help you understand the different ways that your sites’ VirtualHost configurations can be modified:

Note that the file can be called anything as long as it ends in “.conf”. I have chosen “rails.conf” indicating that these custom configurations are specific to rails.

Also note that you will probably need to create the path to this file because it does not exist by default. Therefore, the commands you would need to run are the following:

mkdir -p /usr/local/apache/conf/userdata/std/cobbler/shoemaker.com

nano /rails.conf

You should then point the document root of this site to your rails apps’ “/public” directory. By default, cPanel creates rails apps in /home/<user>/rails_apps. Even though this app will not be under cPanel’s control, it is still ok to place it there. So, an app named “shoemakerapp” located in the rails_apps directory would have the following DocumentRoot line:

DocumentRoot /home/cobbler/rails_apps/shoemakerapp/public

You can also use this .conf file if you need any other custom configurations for the rails site. This might be necessary for several reasons, such as if you need to override some directives. For example, if you enabled MultiViews somewhere, you would want to turn them off since they are not compatible with rails apps.

<Directory /home/cobbler/rails_apps/shoemakerapp/public>

Options -MultiViews # <– MultiViews must be turned off

</Directory>

Include custom settings in httpd.conf

The last action that must be taken is to rebuild the main apache configuration file. This is necessary in order to detect the new custom config file that you have just created. cPanel’s “rebuildhttpdconf” script will add the necessary “Include” lines inside the VirtualHost block. Just run the following commands to backup your current httpd.conf file and rebuild it:

/scripts/rebuildhttpdconf

/scripts/restartsrv_httpd

Your rails application should now be up and running!

Tips

The following are a few things to keep in mind while running passenger.

Restart a rails app

When you restart your app under cPanel’s default rails configuration you do so by restarting the mongrel process that is serving your app. Conversely, you restart an app under passenger simply by updating the timestamp of a touch file named “restart.txt” in the app’s /tmp directory like so:

touch /home/cobbler/rails_apps/shoemakerapp/tmp/restart.txt

Upon seeing that the timestamp of restart.txt has been changed, passenger will restart the app on the next request.