A collection of computer systems and programming tips that you may find useful.
 
Brought to you by Craic Computing LLC, a bioinformatics consulting company.

Friday, November 30, 2007

Running a Rails Applications in a Subdirectory

Part 1: Running a Rails Applications in a Subdirectory

I'm running a Rails application and a separate static web site on the same host.

I want to refer to the static content with a url like http://myserver/public/index.html etc.

I want to refer to the Rails app with a url like http://myserver/db

By default Rails expects an application to reside at the top level of a site, i.e. http://myserver, so I need a way to change this default path. There are two simple steps involved:

1: In config/environment.rb add a line like this at the bottom of the file:

ActionController::AbstractRequest.relative_url_root = "/db"

...where '/db' is the subdirectory where you want your application to appear

This will add that prefix to every URL generated in your Rails app pages and will cause the Rails dispatcher to respond to that path.

2: Adding that prefix will cause your links to stylesheets and javascripts to break. Fix that by adding a symbolic link in your Rails app /public directory

% ln -s . db

... where 'db' is the prefix with no leading slash

Restart your server and try it out.

Part 2: Serving Static Content from Apache and your Rails app from Mongrel

Currently (late 2007) the preferred Web server solution for Rails applications is to use Apache2 as the front end and Mongrel as the Rails application server. All requests come into Apache. Those for a static web site are handled directly, as Apache is great at that job. Requests for the Rails app are proxied to an instance of the Mongrel web server running on a different port. You can find details of this configuration here:
http://mongrel.rubyforge.org/docs/apache.html

These are the steps needed to set up this configuration.

1: Set up the Rails app under a subdirectory as shown in Part 1.

2: Run Mongrel on a port other than 80 as described in the Apache link above. For example, you might run it on port 8000 using this command in your app directory:

% mongrel_rails start -d -p 8000 -e production -P /my/path/railsapp/log/mongrel.pid

3: Configure Apache2 to proxy Rails requests to Mongrel using a VirtualHost block similar to this:

<VirtualHost>
ServerName yourserver.com
ProxyPass /db http://localhost:8000/db
ProxyPassReverse /db http://localhost:8000/db
ProxyPreserveHost on

DocumentRoot /yourpath/static/html
<Directory>
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>

</VirtualHost>


The VirtualHost blocks sets up a host on the standard port 80.

The ProxyPass directives tell Apache to pass any requests with URLs that start with '/db' over to the web server running on the same machine (localhost) at port 8000. It also modifies the responses from that server so that they appear to come from Apache instead of Mongrel. So from the user's perspective the Mongrel server is invisible.

Any other requests are handled by Apache directly and will fetch static content from the directory '/yourpath/static/html', which is where you would put your static web site.

For this to work, your Apache server must load the mod_proxy module, and probably some others. See the Mongrel/Apache link given above for details on that.

Look at the various Apache Proxy options if you need finer control over what gets proxied and what gets served directly. You can set up multiple different Rails apps on the same host in this way and/or multiple Mongrel instances that can serve an application under high load. Again, see the Mongrel/Apache link for details.

Archive of Tips