CherryPy's built-in HTTP server is now pretty robust, but some people might still want to run CherryPy behind Apache.
Whether to run CherryPy exposed or behind Apache depends on many criteria so this question is out of the scope of this HowTo.
This HowTo will show you how to run CherryPy behind Apache, but you can probably adapt it for any other webserver.
There are several ways to run CherryPy behind Apache:
The way it works is very easy to understand. We use a small cgi script called cherrypcgi.cgi as a link between Apache and CherryPy. When someone requests a page, Apache invokes this cgi script. The script then connects to the CherryPy server, gets the page and returns it to Apache.
Of course, it takes a little extra time because a new process is created everytime the script is called. And also because the request and the response go through the script instead of going directly from Apache to CherryPy and back.
But that extra time is really small, so it's not a big problem. (and if you have a really high traffic website, you can use load balancing anyway :-)
This means that you can just start it normally.
If you're on Unix, it's probably better to run the CherryPy server on an AF_UNIX socket. This is what we will do in this example.
To do so, edit the configuration file of the CherryPyServer and enter the following lines:
[server] socketFile=socketFile.soc
Now, just edit the cherrypcgi.cgi file provided with the distribution and modify the line that says:
socketFile='put your socket file here'
The last thing to do is to configure Apache so it will call the cgi script for each request: In Apache's configuration file (commonhttpd.conf for instance), add the following lines (of course, you have to adapt the path of cherrypcgi.cgi):
RewriteEngine on RewriteRule ^(.*) /home/cherrypy/cherrypcgi.cgi$1 [e=HTTP_CGI_AUTHORIZATION:%1,t=application/x-httpd-cgi,l]
It is also possible to tweak cherrypcgi.cgi so it automatically restarts the CherryPy server if it ever goes down. There will be another HowTo on this.
FastCgi works very much like persistent CGI, except the cgi script is constantly running. This means that no process has to be created for each request, which saves a lot of time !
The current implementation of FastCGI in CherryPy is not optimized because the FastCGI script is a standalone script that connects to the CherryPy backend, instead of being directly integrated in the backend. But this method is still a lot faster than persistent CGI.
The FastCGI script is called cherryfcgi.cgi
This means that you can just start it normally.
If you're on Unix, it's probably better to run the CherryPy server on an AF_UNIX socket. This is what we will do in this example.
To do so, edit the configuration file of the CherryPyServer and enter the following lines:
[server] socketFile=socketFile.soc
Now, just edit the cherryfcgi.cgi file provided with the distribution and modify the line that says:
socketFile='put your socket file here'
The last thing to do is to configure Apache so it will connect to the FastCGI script for each request: In Apache's configuration file (commonhttpd.conf for instance), add the following lines (of course, you have to adapt the path of cherrypcgi.cgi):
SetHandler fastcgi-script RewriteEngine on RewriteRule ^(.*) /home/cherrypy/cherryfcgi.cgi/$1 [L]
LoadModule fastcgi_module modules/mod_fastcgi.so AddModule mod_fastcgi.c
And that's it ! Start Apache, start the CherryPy server and it should work.
See Also:
It's easy to configure Apache so it just passes all requests to the CherryPy server, reads the response and passes the response to the client.
This method is a bit faster than persistent CGI because no CGI process needs to be created for each request.
Configuring Apache is very easy:
RewriteEngine on RewriteRule ^(.*) http://localhost:8000$1 [p]
The last thing we have to do is tell CherryPy that it's serving pages for www.cherrypy.org (and not localhost). All it takes is 3 lines of code in the initRequest special function:
def initRequest(): request.headerMap['host']='www.cherrypy.org' request.base='http://www.cherrypy.org' request.browserUrl=request.browserUrl.replace('http://localhost:8000', 'http://www.cherrypy.org')
And voila !
Note, this can also be done with mod_proxy instead of mod_rewrite.
Many thanks to Andreas Kostyrka for this tip.
See About this document... for information on suggesting changes.