No-Framework Ruby on the Web using eRuby on Mac OS X

I have a suspicion that there are a lot of web developers out there who, like me, are eager to start learning more about Ruby but who are stunted by the incredible amount of unfamiliar conventions that are used in Rails. For many of us, our first introduction to Ruby was (or is) through Rails and the challenge of learning both Ruby and Rails at once should not be underestimated; frankly it’s damn hard.

Thankfully, there’s an easier way. Especially if you’re accustomed to “old-school” development workflows that you learned through, say, PHP or perhaps Perl scripting, then ditching Rails and starting purely with Ruby might be the way to go. Doing things on your own without the “magic” of Rails will let you learn Ruby in a simple, yet fully-featured environment, much like the way you might have learned classic CGI programming.

Specifically, by using eRuby, the Embedded Ruby interpreter, you can make Ruby web development feel just like PHP development. Install it, upload an HTML file with some embedded Ruby code in it, and—voila—you have a single-page web application.

Why this tutorial?

Hivemind’s Getting Started with Ruby on the Web is an excellent resource that described this process from start-to-finish for Windows users. In fact, it was after finding that article that I realized web development with Ruby didn’t have to be governed by Rails and, being a web developer like the authors of Hiveminds, I wanted an easy way to use my Ruby knowledge on the Web.

However, I couldn’t find any similar tutorial or walkthrough for those of us who use Macs. Even the Linux walkthroughs are lacking (or at least my Googling skill for them is). After spending a little while successfully getting eRuby set up on my Mac running Mac OS X 10.4 Tiger, I thought I’d share what I learned with others, so I wrote this article. Its content mirrors the one from Hiveminds to a great degree but focuses on getting eRuby installed on Mac OS X instead of Windows (obviously). I imagine these instructions should be pretty similar if not identical for any other *nix-like platform.

The Setup

Getting eRuby installed and configured with your web server is actually pretty straightforward and won’t take an experienced web developer much time at all. All we’re going to need is the Apache web server and the Ruby programming language to start, both of which are already pre-installed on Mac OS X 10.4 Tiger. (And in Mac OS X 10.5 Leopard, Apple is even shipping new Macs with Ruby On Rails preconfigured, but that’s a subject for another time.) However, Apple typically ships an older copy of Ruby than is readily available, so you might choose to use a newer version of Ruby that you download yourself.

The easiest way to get a copy of eRuby (and an updated Ruby, if you want it) is with a package manager such as MacPorts. With MacPorts installed (which is a simple, standard package installation downloadable from the MacPorts home page), simply run

sudo port install eruby

from your terminal to download the latest stable Ruby and eRuby in one fell swoop. After this runs, you’ll have a new Ruby in /opt/local/bin/ruby and an eRuby in /opt/local/bin/eruby. Alternatively, of course, you could compile and install eRuby yourself. Instructions for that are on the eRuby homepage.

As a quick test to see if everything is installed and working correctly, create a plain text file with your favorite editor that contains the following code:

Hello world! The time is now <%= %>.

All this does is print out a “Hello world!” greeting and then announces the current time (as reported by your system clock, of course).

If you named the above file helloworld.rhtml then you can feed this file to the eruby interpreter as follows:

eruby helloworld.rhtml

Note that the file extension doesn’t actually matter. You could use .erb, if you like, or any other arbitrary file extension. The file extension is, as you’ll see later, only used for telling Apache which kind of file it is. So once you come up with file extension you like, stick with it. The standard file extensions are either .rhtml or .erb, so I’d recommend using one of those. (I prefer .erb, myself, since I don’t necessarily only want to create HTML pages. I might want to create XML documents like news feeds or even XML databases, so .erb seems a more reasonable file name extension, though most of the eRuby documentation uses .rhtml.)

If things worked properly, you should see output similar to the following:

Hello world! The time is now Wed Oct 24 21:58:54 -0400 2007.

Serve it up!

Now that eRuby is installed and working, the next step is to set it up as a CGI so that when your web server (Apache, in my case) fetches the file it will first feed it through eRuby for processing before sending it back to the browser. The simplest way to do this is to configure Apache to use a specific directory somewhere on your filesystem as a CGI directory—that is, a directory whose contents are all treated as CGI programs. You do this via Apache’s ScriptAlias directive.

Conveniently, standard installations of Mac OS X already come with a CGI directory. It’s located at /Library/WebServer/CGI-Executables. This directory is just like any other, except that Apache treats it specially. It treats it specially because Apache’s configuration file, /etc/httpd/httpd.conf contains a line of text that reads as follows. (On a standard installation of Mac OS X client, this is line 671 of the file.)

ScriptAlias /cgi-bin/ "/Library/WebServer/CGI-Executables/"

This line basically just tells apache, “Treat every file in the /Library/WebServer/CGI-Executables directory as though it were a CGI program.” So, since that’s how we’re treating eRuby, we’re going to want to put our eruby binary in that directory. However, we don’t actually want to make copies of the binary. Having too many copies of a program on your system can easily get confusing. So instead, we’ll make a symbolic link (or an alias to use the classic Mac terminology) to the binary.

ln -s /opt/local/bin/eruby /Library/WebServer/CGI-Executables/eruby

With our eruby CGI executable in the proper place for Apache to find it, we can now tell Apache which files we want it to send to this program. We do this using the AddHandler and Action directives.

AddHandler simply tells Apache to treat files with a certain extension in a certain way. For instance, you can say something like, “Treat all files ending in .php as PHP scripts.” Similarly, you can (and will) tell Apache, “Treat all files ending in .rhtml or .erb as eRuby CGI pages.”

To do this, we add the following line to our /etc/httpd/users/username.conf file somewhere inside the <Directory> and </Directory> block. Naturally, replace username with, of course, your Mac OS X user’s short name:

AddHandler rubypage .erb .rhtml

Again, this just tells Apache that files ending in .erb and .rhtml should be treated the same way other rubypages are treated. But how are eRuby pages supposed to be treated? They’re supposed to be handed off to the eRuby program, of course, so we need an Action directive that applies to the rubypage handler we just defined.

Right below the above line, add the following line, too:

Action rubypage /cgi-bin/eruby

This line tells Apache that any file that it is treating as a “rubypage” file should be sent to the program at the URL accessible at /cgi-bin/eruby, which we’ve defined earlier to be our symbolic link to the eruby interpreter.

Your completed user-specific Apache configuration file should now look something like this:

<Directory "/Users/username/Sites/">
    # Let eRuby files get parsed through the proper CGI binary
    AddHandler rubypage .erb .rhtml
    Action rubypage /cgi-bin/eruby

Are You Being Served?

That’s it, everything should now be in place. To make sure, move your earlier helloworld.rhtml file into your user’s Sites folder, and now simply point your browser to http://localhost/~username/helloworld.rhtml (again, replacing username with your Mac OS X user short name, of course). Congratulations, you’re serving up Ruby-coded applications via eRuby.

Additional Reading

This is just the set up, of course. Now the real fun begins: learning Ruby. Here are some suggested places to start.

Naturally, feel free to leave comments if you have more resources that you found helpful.

16 replies on “No-Framework Ruby on the Web using eRuby on Mac OS X”

  1. Interesting article but it didn’t quite work for me in 10.5.

    Port installed eruby just fine and I was able to view helloworld.rhtm.

    The first issue I encountered was with Apache. 10.5 uses Apache 2 by default and doesn’t migrate Apache 1 settings over so I had to
    cp /etc/httpd/users/*.conf /etc/apache2/users/
    just to get localhost/~username running again.

    The creation of the shortcut (eruby -> /opt/local/bin/eruby ) proceeded without issue and I made the changes to the user-specific conf file but it throws a permissions error:
    You don’t have permission to access /cgi-bin/eruby/~danieldeverell/test.rhtml on this server.
    when I access http://localhost/~danieldeverell/test.rhtml (after restarting Apache).

    Any thoughts?

    As an aside – I am able to run .rb files from my cgi-bin
    i.e. http://localhost/cgi-bin/simple_cgi.rb

  2. Hmmm…at first glance it sounds like either Apache isn’t configured to allow access to the CGI binary or to your local Sites directory, or else it’s actually thinking that you’re trying to get to a file called /cgi-bin/eruby/~danieldeverell/test.rhtml. In either case, take a look at the error log to see if anything more helpful appears there. (You might also try raising the verbosity using the LogLevel directive.) If troubleshooting on your own fails, I’ve always found the folks in #apache on Freenode are very helpful.

    If you figure it out, I’d love to hear what the problem was, as I’ve yet to use Apache 2 heavily. Thanks.

  3. I’m having the same problem as Daniel (I’m using os x 10.5.1).

    I get the following error:
    You don’t have permission to access /cgi-bin/eruby/~liamks/erubytest.rhtml on this server.

    according to the error log:
    [Fri Dec 28 00:06:25 2007] [error] [client] Symbolic link not allowed or link target not accessible: /Library/WebServer/CGI-Executables/eruby

    The link should be fine as I copy and pasted “ln -s /opt/local/bin/eruby /Library/WebServer/CGI-Executables/eruby” into the terminal window. I’ve checked in /opt/local/bin/ and eruby does exists. I’ve checked in /Library/WebServer/CGI-Executables/ and the eruby shortcut does exist… Not sure what to do on this!

  4. Liam, try adding the following line in the appropriate Directory block for your set up:

    Options +FollowSymLinks

    Or, just make sure “FollowSymLinks” is a listed option in the Directory block for your home user folder. That’s the directive that tells Apache to follow symlinks to their targets. I thought Apple set up Apache that way by default, but maybe I was mistaken about that…?

  5. Thanks for your quick reply. According to httpd.conf it looks like FollowSymLinks is enabled by default:

    # First, we configure the “default” to be a very restrictive set of
    # features.

    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all

    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all

    When I modify the following to include FollowSymLinks (for liamks.conf) the same error persists:

    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all

    AddHandler rubypage .erb .rhtml
    Action rubypage /cgi-bin/eruby

    Once again, I appreciate your help!

  6. Woops, the bracketed Directory stuff got filtered out. Here’s what each options block corresponds to:

    Directory /
    Directory “/Library/WebServer/Documents”
    Directory “/Users/liamks/Sites/”

  7. Hmm. Are you positive both the symbolic link and the eruby binary have the proper UNIX permissions set on them? You should get output similar to the following on your machine when you check:

    maymay$ ls -l /Library/WebServer/CGI-Executables/
    total 8
    lrwxr-xr-x   1 admin  admin  20 Oct 25 00:32 eruby.cgi -> /opt/local/bin/eruby

    Note the first chunk of the third line that indicates the link is world-readable and world-executable. For basic information on UNIX permissions, see this tutorial, for example.

  8. Output seems the same.

    liamks$ ls -l /Library/WebServer/CGI-Executables
    total 24
    lrwxr-xr-x 1 liamks admin 20 27 Dec 23:43 eruby.cgi -> /opt/local/bin/eruby

    I’ve tried a million different combinations with my liamks.conf file… a few with httpd.conf and not luck.

  9. That’s funny. Unfortunately, I don’t have a Mac OS X 10.5 system on which to test; I’ve only got this working on Tiger. I would double-check all of your Apache configuration files and make doubly sure that you’re allowing symbolic links. One way to test this is to simply delete the symbolic link to the eruby binary and replace it with a copy of the real binary, like so:

    rm /Library/WebServer/CGI-Executables/eruby.cgi
    cp /opt/local/bin/eruby /Library/WebServer/CGI-Executables/eruby.cgi

    Then try again. If this works, you know the problem is your Apache configuration. In that case, comb through your Apache files to make sure there are no includes or other directives overwriting your modifications. One such file that typically does this is /etc/apache2/default-server.conf, so be sure to check that too.

  10. rm /Library/WebServer/CGI-Executables/eruby.cgi
    cp /opt/local/bin/eruby /Library/WebServer/CGI-Executables/eruby.cgi

    That seemed to solve the problem – obviously it’s a problem with the Apache configuration! Thanks for your help!

  11. Great, Liam; glad I could help. Seems as though there’s a difference in the default configuration between Apache 2 and Apache 1.3 as delivered on Mac OS X. As soon as I get a Mac OS X 10.5 machine to play with, I’ll have to update this article. Until then, if anyone else knows the specific changes needed to make this work with Apache 2 on Mac OS X 10.5, please let me know.

    Oh, and Happy New Years everyone!

  12. I had the same problem, but I changed:

    <Directory “/Library/WebServer/CGI-Executables”>
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all


    <Directory “/Library/WebServer/CGI-Executables”>
    AllowOverride None
    Options FollowSymLinks
    Order allow,deny
    Allow from all

    in /etc/apache2/httpd.conf

  13. I’m getting stuck at the first step. I input

    sudo port install eruby

    in the Terminal, and it returns

    Waiting for lock on /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_devel_readline/work/.macports.readline.state

    and just sits there. I have the latest MacPorts installed.

  14. Thanks Meitar, it was a problem with MacPorts. I did something funny when I first installed it, so I reinstalled it and everything worked fine.

    I put the AddHandler and Action stuff in a .htaccess to better mimic my host, and I ran into the problem Liam was having (I’m on Tiger). Kevin’s suggestion fixed the problem.

    Thanks for the great article and helpful comments!

Comments are closed.