I've been wanting to drop mod_python since the day I installed it. After the saga of setting it up, I was left feeling unclean. So I sat down yesterday and started downloading new versions of stuff. Apache, mod_fastcgi, Python, Subversion, PHP… you name it. My biggest concerns were upgrading to Python 2.5, and switching this site (and others) from mod_python to mod_fastcgi. But I sure am glad I did. Deploying a Django site was never my favorite thing to do under mod_python, but with mod_fastcgi, it became an almost joyous experience.
Here's the VirtualHost
entry for this site running under mod_python:
<VirtualHost *:80>
ServerName theidioteque.net
ServerAlias www.theidioteque.net
<Location />
SetHandler python-program
PythonPath "['/home/dcwatson/projects'] + sys.path"
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE idioteque.settings
PythonDebug Off
</Location>
Alias /static /home/dcwatson/projects/idioteque/static
<Location /static/>
SetHandler None
</Location>
</VirtualHost>
And here it is running under mod_fastcgi:
<VirtualHost *:80>
ServerName theidioteque.net
ServerAlias www.theidioteque.net
Alias /static /home/dcwatson/webapps/idioteque/static
ScriptAlias / /home/dcwatson/webapps/idioteque.fcgi/
</VirtualHost>
Note the trailing slash at the end of the .fcgi script. Forget it, and your links won't work. My idioteque.fcgi
script looks just like the one found on django's fastcgi documentation.
Setting up trac was just as easy. I simply copied the trac.fcgi
script to my own trac-idioteque.fcgi
script and set the TRAC_ENV environment variable at the top of it, as described here. Now my VirtualHost
entry is three lines:
<VirtualHost *:80>
ServerName code.theidioteque.net
Alias /chrome/common /usr/local/python/share/trac/htdocs
ScriptAlias / /home/dcwatson/webapps/trac-idioteque.fcgi/
</VirtualHost>
I should probably note that I have Allow from all
set in my root Directory
in httpd.conf
. This is probably not a terribly good idea, but it saves explicitly allowing access to any directory I want to serve files from.
Apologies for the particularly dry post, but if you haven't noticed, this blog seems to be geared around problems I encounter and my solutions to them. If your problem is mod_python, mod_fastcgi is your solution.
I heard it wasn't good to run Django with FastCGI, is there a reason for this or is it just a rumor?
Where did you hear that? While the Django docs specifically endorse the mod_python route, there are official instructions for setting it up using FastCGI. I've found it to be fewer lines of configuration, and more stable in my case.
Curious, I had no idea using a ScriptAlias like that would work. Do you have any FastCGIServer or AddHandler directives listed?
I ask this because I wrote the current fastcgi documentation that's on djangoproject.com, and because I was unable to find any other workable alternatives, I ended up having the docs use mod_rewrite. (I use lighttpd in all my current deployments, and so apache config came as an afterthought)
I wonder, is Apache calling that script using CGI and not FastCGI? Flup will fall back to serving normal CGI if the script is called without the proper fcgi environment / file descriptors. One thing to do would be to check the output of
ps ax
and see if there's a persistent fcgi process running or if it only spawns per-request.I'm rather intrigued as to how your setup is working; feel free to fire me off an email, perhaps I'll use your setup in future versions of the fastcgi documentation.
I probably should have mentioned I do have an AddHandler line in my httpd.conf:
I don't use a FastCGIServer/FastCGIExternalServer line because they can't be used in VirtualHost blocks, and I like to keep things as organized and isolated as possible. One of the first things I did was check the output of
ps aux
- one persistent instance is created the first time the site is hit.I'm gonna have to try this on my host to see if I can get it working. Many hosts dont support mod_python.
On centos (selinux), you probably also need to add FastCgiIpcDir /var/www/html/fastcgiIPC
It took me a while to figure this out - the apache process complains about not being able to bind() .
For obvious reasons, I would recommend that the next part of this tutorial should come out tomorrow, and deal with the topic of "how do I integrate captcha support into the Django comment system".
:-/
It is easy to run into other security pitfalls when generating your own CAPTCHAs. For instance, many websites will store the answer to a CAPTCHA in a session on the server side. Once the form has been submitted, the web application will forget to clear this value. A spammer can then re-use this session multiple times with the same CAPTCHA answer, because the application will not change the answer on the server side until the CAPTCHA image is re-downloaded.
Leave a comment in reply to Dan Watson