The Web as filtered (and hopefully enriched ;-) by Adrian McEwen

Removing "public" From the URL of Rails Apps

Or… “How to get Ruby on Rails running on 34sp.com.”

One of the challenges of running my own business has been keeping on top of the multitude of things I have to get done. David Allen’s book Getting Things Done (or GTD) has been a very useful guide in this particular area, and I’ve been slowly developing my own to-do list web application to help me to put GTD into practice.

It’s also given me a chance to try out Ruby on Rails, the web development framework darling of Web 2.0. And I can see why it’s been getting so much hype - it’s very quick to get something up and running, which you can then start to tweak and extend; the documentation is pretty well laid out, so I’ve found it much easier to delve into than, say, when I started learning PHP; and the built-in AJAX support, and layout system lend themselves well to rapid development of web apps.

One thing I have had a bit of trouble with is deploying my Rails app on my existing webspace. The standard directory structure for Rails maps the web app root into a directory called “public” and if you aren’t going to have your app sit at the root of the website (i.e. http://www.myserver.com/), you seem to end up with an unnecessary “/public” in your URLs. For example, I want my todo-list to live at http://www.mcqn.com/tedium/ but by default it would actually be at http://www.mcqn.com/tedium/public/.

This is how I’ve worked round it on an Apache 1.3 server using fastcgi. I don’t make any claims or guarantees for the information other than it seems to work for me. If there’s a better way of doing this, or if there are problems with this approach, I’d love to hear about them, as then I can improve my web app and these instructions.

First off, a quick note about Ruby on Rails support with 34sp.com. They are only just starting to roll out Rails support on their servers, but were very helpful in getting it up and running on my server when I asked. This thread seems to be the place to check first to see what the latest status is for Ruby on Rails support at 34sp.com.

Assuming your web server root directory is called httpdocs (as mine is) and the place you want you’ve generated the Rails app in a directory called tedium (as I have), your directory structure should look something like this:

httpdocs/ tedium/ app/ config/ doc/ lib/ log/ public/ images/ javascripts/ stylesheets/ script/

Out of the box you should be able to point your browser at http://www.yourserver.com/tedium/public/ and be presented with your Rails app. http://www.yourserver.com/tedium/ would be nicer though.

HowToUseRailsWithRewrittenURLs in Ruby on Rails explains how to have your web server automatically redirect people, so if you went to http://www.yourserver.com/tedium/ it would automatically take you to http://www.yourserver.com/tedium/public/, but I don’t think that’s good enough. I want my URLs to be as clean as possible.

So what I did was to copy the fastcgi dispatcher scripts (that’s dispatch.cgi, dispatch.fcgi, and dispatch.rb) and the .htaccess file from /httpdocs/tedium/public/ into /httpdocs/tedium. Then I had to edit the dispatcher scripts so that they could still find the environment directory. In each file, change the string "/../config/environment" into "/config/environment".

That should get most of your Rails app working at the new location of http://www.yourserver.com/tedium/, but it won’t be able to find any images, javascript files or stylesheets as they’re still in public. We can fix that with some mod_rewrite instructions in the .htaccess file.

I uncommented the RewriteBase line, and changed it to my directory name - in this case tedium:

#RewriteBase /myrailsapp

became:

RewriteBase /tedium

Then I added a new rewrite rule. This checks to see if the requested file exists in the public directory - if it does then the URL gets rewritten to include public, otherwise we let Ruby on Rails deal with it. So our final step changes: RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

in the .htaccess file into:

See if this is a file in “public”, and if it is, just redirect to it

RewriteCond /path/to/your/httpdocs/tedium/public/$1 -f RewriteRule ^(.+) public/$1 [L] RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA]

Otherwise, if this request isn’t just for an existing file, give it to

the Ruby on Rails dispatcher

RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] </code>

Now you should be up and running with your new Rails app at its clean new URL. Hope that’s helped.

This page is part of Adrian McEwen's blog, McFilter. Explore more in the category pages or archives below.

Subscribe to updates with the RSS feed (what's an RSS feed?)