Using Zope With Apache

A step-by-step guide to the process of serving up your Zope content through Apache.

The Art Of Compromise

So you've read the advertising, heard all your friends talking about it, and finally decided to download your own copy of Zope. You've installed it, played with it, maybe even written a few DTML pages or created some small Zope applications. And you're sold. You're ready to install it on your Web site, trash your old HTML and PHP scripts, and convert everything into Zope objects.

Whoa there, big fella. Hold on just a second.

While Zope is a remarkably full-featured solution, it's not always the best one for a live Web site or Web application. If you're developing a complex Web application with sophisticated business logic and lots of interconnected routines, Zope is a great sandbox to play in. If, on the other hand, you're merely putting up Grandma's chocolate chip cookies on the Web, you're going to find Zope way too complex for your relatively-simpler needs.

Luckily for you, there is a compromise. You can hook Zope up to Apache so that you get the best of both worlds, combining Apache's legendary stability and flexibility with Zope's everything-is-an-object paradigm to create an efficient, scalable and robust foundation for your Web site.

And that's where this article comes in. Over the next few pages, I will be discussing the myriad ways in which Apache can be connected to Zope, together with my experiences on how easy or difficult each technique is. I will assume here that you're working on a Linux box, and have a working Zope 2.5 installation with super-user access.

Let's get going!

A Few Good Reasons

If you've been playing with Zope for a while, you already know that Zope comes with its own HTTP server, which can be used to serve Zope documents to any connecting client. While this ZServer is a remarkably full-featured and powerful application, it's still not as easy (or as flexible) as Apache, which is still the planet's numero uno Web server.

There are a number of reasons why you might want to hook Zope and Apache up together:

  1. If you're a Webmaster transitioning an existing site to Zope, it's unlikely that your entire site will be build around Zope. It's more likely that you'll have some static HTML pages and some dynamic, interactive sections which are populated via user activity. In such situations, it's not very optimal to have Zope serve up the static pages; Apache is better suited to the task, and also more efficient at it.

  2. If you're running multiple virtual hosts on the same site, you're probably going to have trouble configuring Zope to handle them. It's far easier (not to mention less time-consuming) to have Apache handle the virtual hosting for you, and have Zope simply serve up the pages as needed.

  3. If you're already using Apache's HTTP authentication feature, you might find it inconvenient to switch over to Zope's authentication system. In such situations, it might be preferable, and less disruptive to your users, to disable Zope authentication and continue to use Apache's authentication database - even on Zope-generated pages, or within Zope's management interface.

Now, I'm not going to cover each of these applications in detail in this article; rather, I will be focusing on the technicalities of using the Apache Web server to pass requests on to Zope, and to serve up the returned Zope content in a transparent manner. In order to do this, you will need to reconfigure and recompile your Apache server to include support for a few additional modules. Here's a list of what you're going to need - download it now, and then proceed to the next page.

The Apache Web server, from http://httpd.apache.org/

The FastCGI module, from http://www.fastcgi.com/

As I said before, I'm assuming that you already have a working Zope installation; if you don't, drop by http://www.zope.org/ and get yourself set up.

When Persistence Pays Off

There are a number of different ways to get Apache working with Zope - however, all of them rely on using CGI to pass Apache requests to Zope for processing. The first of these involves using persistent CGI, or PCGI.

When Zope is first installed, a file named "Zope.cgi" is created in the Zope installation directory. This is the file you will need in order to serve up Zope data via Apache. Copy this file to your Apache server's "cgi-bin" directory, and set its ownership and permissions appropriately.

$ cp /usr/local/Zope/Zope.cgi /usr/local/apache/cgi-bin/
$ chmod 711 /usr/local/apache/cgi-bin/Zope.cgi

Next, start Zope with the "-p" command-line parameter (this tells Zope to use PCGI).

$ cd /usr/local/Zope
$ ./bin/python z2.py -p /usr/local/apache/cgi-bin/Zope.cgi

Zope should now start up. Verify that it is running by browsing to the URL http://your.server:8080/ and the URL http://your.server:8080/manage/ (for the management interface)

Next, start up Apache.

$ /usr/local/apache/bin/apachectl start

You should now be able to access the Zope pages through CGI, by browsing to the URL http://your.server/cgi-bin/Zope.cgi - in other words, accessing Zope content via Apache.

The Writing On The Wall

Now, while this is fairly simple, there's one very important caveat with this method. You won't be able to access the Zope management interface via PCGI, because Apache has trouble passing authentication headers over the CGI "bridge" that's been constructed between Zope and itself.

Luckily, there does exist a solution for this (although it comes with a caveat of its own, discussed on the next page). This solution involves using Apache's URL rewriting engine to artificially pass the authorization credentials to Zope over CGI.

In order to do this, first make sure that your Apache build includes support for URL rewriting (you can do this by looking for "mod_rewrite.c" in the output of "httpd -l"). If it does, great - skip the configure-build-install process below and jump straight into configuring the server. If not, you'll need to recompile Apache with support for URL rewriting.

First, untar the Apache distribution to a directory on your system.

$ cd /tmp/sources
$ tar -xzvf apache_1.3.20.tar.gz

Next, configure Apache to activate the URL rewriting module.

$ cd /tmp/sources/apache_1.3.20
$ ./configure --enable-module=rewrite

Compile and install the package.

$ make
$ make install

All done? Now add the following lines to Apache's "httpd.conf" configuration file.

RewriteEngine on
RewriteCond %{HTTP:Authorization}  ^(.*)
RewriteRule ^/Zope(.*) /usr/local/apache/cgi-bin/Zope.cgi/$1 [e=HTTP_CGI_AUTHORIZATION:%1,t=application/x-httpd-cgi,l]

This tells the server to use its URL rewriting engine to automatically pass all URLs containing /Zope to the "Zope.cgi" script. Simultaneously, it sets the environment variable HTTP_CGI_AUTHORIZATION to reflect the current authentication status, thereby (hopefully) solving the authentication problem.

Restart the server, and try accessing the URL again. This time, Apache should successfully pass your authentication credentials to Zope, and you should be able to access the Zope management interface.

If it didn't work, you're not toast yet - flip to the next page for an alternative solution.

The Fast And The Furious

Now, while the procedure on the previous page does seem to work in some cases (at least according to all the documentation I read and some of the posts in the online newsgroups), I have to admit that, despite my best efforts, I was unable to get the URL rewriting to work correctly on my system. If you had the same problem, then be of stout heart, because there does exist an alternative solution.

This alternative is FastCGI, which works just as well, and is much easier to install and use. First, untar the Apache distribution to a directory on your system.

$ cd /tmp/sources
$ tar -xzvf apache_1.3.20.tar.gz

Next, untar the FastCGI distribution

$ tar -xzvf mod_fastcgi-2.2.12.tar.gz

and move the contents of the newly-created directory to <apache-source>/src/modules/fastcgi

$ mv mod_fastcgi-2.2.12 apache_1.3.20/src/modules/fastcgi/

Configure Apache to activate this FastCGI module.

$ cd /tmp/sources/apache_1.3.20
$ ./configure --activate-module=src/modules/fastcgi/libfastcgi.a

In case you're wondering, no, there isn't an error in the line above - the file "libfastcgi.a" doesn't exist at the moment, but it will soon.

Compile and install the package.

$ make
$ make install

At this point, you can verify that the FastCGI module has been compiled into the server by executing the httpd binary with the "-l" parameter (look for the entry "mod_fastcgi.c" in the resulting output)

Next, configure Apache so that it knows how to handle FastCGI. Pop open Apache's "httpd.conf" file and add the following lines to it:

FastCgiExternalServer /usr/local/apache/htdocs/zope -host localhost:8889 -pass-header Authorization

<Location /zope>
SetHandler fastcgi-script
</Location>

The FastCgiExternalServer directive defines the file "/usr/local/apache/htdocs/zope" as a FastCGI application, one that will be started and stopped manually. It also means that any request for this file from a client browser will automatically be handled by FastCGI.

The "-pass-header Authorization" argument to the FastCgiExternalServer directive instructs Apache to pass authentication information to the FastCGI application; this will (hopefully) solve the authentication problems experienced with PCGI.

Now, shift the action over to Zope. You'll need to start Zope with a couple of additional configuration parameters, so that it knows it needs to use FastCGI. Here's how:

$ cd /usr/local/Zope/
$ ./bin/python z2.py -D -F 8889

This tells Zope to use FastCGI, and to run on port number 8889. If you'd prefer to use a UNIX domain socket instead of a TCP port, you can replace the port number with the path to the socket.

Zope should now start and run silently in the foreground.

Finally, start Apache.

$ /usr/local/apache/bin/apachectl start

At this point, you should be able to browse to the URL http://your.server/zope/ and view the Zope screens. All content under the /zope/ "directory" will be served up by Zope; all other content will be served by Apache.

You'll notice, also, that if you go to the Zope management interface, at http://your.server/zope/manage/, you'll have no trouble logging in (so long as you have the right credentials). Thus, FastCGI very neatly solves the authentication problem PCGI had - and that's why I'd recommend this approach over the previous one.

Performing By Proxy

Of course, there are other ways to get Zope and Apache talking as well. One of the most interesting involves using Apache's proxy module to transparently pass Zope requests to the ZServer.

The first step is to make sure that your Apache build includes support for the proxy module (look for "mod_proxy.c" in the output of "httpd -l"). If it doesn't, you can recompile Apache by doing the following:

$ cd /tmp/sources
$ tar -xzvf apache_1.3.20.tar.gz
$ cd apache_1.3.20
$ ./configure --enable-module=proxy
$ make
$ make install

Once the program has been installed, pop open "httpd.conf" and add the following lines to it:

ProxyPass /community http://localhost:8080/
ProxyPassReverse /community http://localhost:8080/

This tells the server to intercept all requests for the URL /community (the first argument to ProxyPass), and redirect them to the Zope server (the second argument).

While this approach is simple, it does have a few glitches. Take a look at http://www.zope.org/Members/anser/apache_zserver for a detailed explanation of these problems, together with some very elegant hacks that solve them quite well.

Zip Zap Zoom

In the event that all of this configuration and recompilation is not to your taste, there is a far simpler option available to you. The nice guys at Zope.org have created a pre-compiled, pre-configured package that's designed to simplify Apache/Zope integration - it's called Zap ("Zope plus Apache in precompiled form") and it's available for free download from http://www.zope.org/Download/Releases/Zap-1.1.0

This pre-compiled package comes with its own custom "httpd.conf" file, designed specifically to get the server up and running with Zope. It contains binary versions of both Apache and Zope, and is a breeze to set up and install, so long as there isn't any mismatch between your system libraries and the precompiled binaries in the Zap distribution. Check it out, if only to get a better idea of how to configure Apache to work with Zope.

And that's about it for the moment. Whatever you've learned in this tutorial is just the tip of the iceberg - there's a lot more you can do with the Apache/Zope combination, including running multiple Zope-based virtual hosts and replacing Zope's built-in authentication scheme with Apache's HTTP authentication system. I'll be talking about those items in a follow-up piece soon - so stay tuned!

Note: All examples in this article have been tested on Linux/i586 with Zope 2.5. Examples are illustrative only, and are not meant for a production environment. Melonfire provides no warranties or support for the source code described in this article. YMMV!

This article was first published on29 Mar 2002.