Monday, 14 July 2008

Using Apache as a front-end for Seaside

I'll admit it, configuring Apache scares the bejeezus out of me. The documentation seems to be so focused on the trees, that the wood becomes an impenetrable, gloomy forest. I guess I'm not alone in this, which makes Ramon Leon's posts on configuring Apache with Seaside(1, 2, 3) so useful.
Despite this, I've still steered clear of going near Apache, until Ramon posted a sample extract of configuration text. Now, cut-and-paste is something I can do, so I decided to give it a go.
I'm on Mac OS X, so Apache is installed and running by default. Despite my earlier protestations, I have played with Apache before, so I knew that httpd.conf was the key file to control how Apache runs. A bit of poking about in man files uncovered the location of the file I needed: /private/etc/apache2/http.conf.
I opened a Terminal and cd'ed to /private/etc/apache2/ where I could execute sudo vi httpd.conf which prompted me to enter my password to edit this administrator file, and then allowed me to start hacking. I wanted to leave my existing configuration as untouched as possible, so below the line:
Listen 80
I added a new line:
Listen 81
which would start Apache listening on port 81 as well as port 80. I could then use port 81 for my experimentation.
Typing sudo /usr/sbin/apachectl restart caused Apache to restart, hopefully loading my change.
I then tried browsing http://localhost:81/

Success (so far) - Apache is trying to deal with my request, and using its default handler.
Now, I'd noticed an interesting line at the bottom of httpd.conf:
Include /private/etc/apache2/other/*.conf
which meant that I could make any other changes in a separate file. So sudo vi other/seaside.conf opened a new .conf file, into which I typed:
    #DocumentRoot /var/www/myExamplePath
    RewriteEngine On
    ProxyRequests Off
    ProxyPreserveHost On
    UseCanonicalName Off
    # if the path doesn't exist, rewrite it to be a Seaside file ref
    RewriteRule ^/seaside/files(.*)$ http://localhost:8080/seaside/files$1 [P,L]

    # redirect all requests to seaside - configure this as required
    RewriteRule ^/(.*)$ http://localhost:8080/seaside/$1 [P,L]


Which (when you put back the angle brackets that Blogger eats on the first and last lines) is taken directly from Ramon's post. It does two useful things. It takes any requests coming in to port 81, and first checks to see if you're requesting a physical file, and if so, serves it up (useful for the static parts of your site). If not, it passes them on to Seaside on the appropriate port, adding the standard /seaside prefix (so this is hidden from the outside world, which is a nice touch). Restarting Apache again and this time browsing http://localhost:81/examples/counter got me:

Again, good news. However, when I tried to navigate around, or use applications that made use of built-in #style and #script methods, things started to go wrong. The reason here is that Seaside prefixes its generated relative URLs with /seaside. So I simply added the following:
# re-write all requests starting with seaside - these links are exposed
# by the application internally. Alternatively, you can
# re-configure Seaside to change the urls it generates.
RewriteRule ^/seaside/(.*)$ http://localhost:8080/seaside/$1 [P,L]

into the virtualhost directive, and re-started Apache once more. This time it all worked like clockwork.
Twenty minutes of not very challenging experimentation, and I now have Apache working as my front-end webserver. That means, all the handling of static files can be done outside of Squeak, I can configure my responses if the Squeak images crashes, I get access to all of Apache's features such as logging, SSL etc. Not a bad half-hour's work really.


Ramon Leon said...

My config assumed the basePath on the Seasdie app was set to /, so Seaside generates the URL's correctly.

Michael Davies said...

Hi Ramon,

Thanks for replying.

I knew there was a tweak that could be applied to Seaside, but didn't want to distract myself from the excitement of configuring Apache.

Given your hint, I've played with the settings of the application in the /seaside/config configuration screen and what seems to work is setting the "Server Path" to the same as the application path - eg to "/my/applicationName" - given that I'm now able to remove the addtional lines, and revert to your original sample.

Thanks for your help.

Damien said...

Michael, your way to do it has the advantage that it keeps the default configuration of Seaside, so it will work both through apache and by connecting to Kom directly. Nice for debugging.

I wonder if, instead of the Seaside base path, applications couldn't be directly mounted at different points in Kom ?