2006-09-23

Ignorant -> Newbie: Running Django using SCGI through LightTPD

To get Django using SCGI under LightTPD turned out to be a pain. No one had fully documented what was required to get it to work. It also turned out to be a slight pain in the ass for me since I of course decided to do things in LightTPD that are not totally simple.

First thing is to get Django executing under SCGI. That requires downloading django-scgi.py (I think it is by some guy named Georg Bauer, but I can't read German). Next, you need to install flup so that you have a way to drive the WSGI interface for Django. With those two things installed you have what you need to run Django using SCGI.

But the step people neglect to mention prior to running anything is that there is some configuring. You need to set your DJANGO_SETTINGS_MODULE environment variable. That requires tweaking your PYTHONPATH so that your web site's Django directory is on it. I wonder how much work it would be to cut all of this out and just write a LightTPD WSGI module?

With that all done I launched the SCGI process to be bound to a IP and port and run as a daemon (run django-scgi.py with no arguments to get the listing of options). Now you need to get LightTPD running.

For that I needed to adapt the Django docs for running it with FastCGI to use SCGI. The LightTPD docs for SCGI tell you to read the FastCGI docs anyway, so that switched over fine. But when I pulled up the admin interface, it looked all ugly. Turned out the CSS was not being served.

When running Django as its own web server it knows where to fetch all of its own files. But when you use it as a SCGI process, it no longer fetches its own media files. That required tweaking LightTPD so that it had an aliasing rule for any addresses that go to ``/media/`` to actually fetch from django/contrib/admin/media/ and have LightTPD serve that. That meant having a conditional rule for my www.drbrett.ca host that had LightTPD serve up the media files while everything else went through the SCGI process (my personal static media goes through drbrett.ca as a separate LightTPD rule). In the end, the LightTPD rule ended up being:


$HTTP["host"] == "www.drbrett.ca" {
$HTTP["url"] =~ "^/media/" {
alias.url = ("/media/" => "/home/brett/installed/lib/python2.4/site-packages/django/contrib/admin/media/")
}
else $HTTP["url"] !~ "^/media/" {
scgi.server = ("/" =>
(
("host" => "127.0.0.1",
"port" => 8080,
"check-local" => "disable")
)
)
}
}

More work than I was expecting, but now I have django-scgi.py running flup to maintain some SCGI process of Django with LightTPD handling all static file serving as needed.

Blah. As I have said before, I will have my LightTPD config file online for people to work off of once I get my site up and have a personal files section so that no one else has to do this all from scratch.

11 comments:

dariaspop said...

Thank you for doing all of he work! When I get where I need this I'll know where to look.

Brian Zhou said...

I found nginx is easier to setup, just redirect or reverse proxy to the backend instances and you're done.

Anonymous said...

The other thing you can do, rather than using the conditional media serving, is use a rewrite rule using lighttpd's mod_rewrite. It allows you to specify multiple static URLs as you need, such as for example things like favicon.ico and robots.txt

If you look at the lighttpd section of the official fcgi documentation ( http://www.djangoproject.com/documentation/fastcgi/#lighttpd-setup ) and then simply replace "fcgi" with "scgi" it works pretty well like that.

Brett said...

I know I can use mod_rewrite to change the relative URL portion of the URL, but I can't rewrite the actual hostname. Everything that is directly served from www.drbrett.ca is going to be dynamic while everything from drbrett.ca is going to be static.

So if mod_rewrite supported rewriting the hostname or if I was willing to change things so that I could serve static files from www.drbrett.ca then it would be fine. But since I don't want to do that mod_rewrite doesn't quite do what I want.

Anonymous said...

Forgive the ignorance but what does using SCGI get you over FastCGI?

Brett said...

Most people argue that SCGI is just a plain better protocol than FastCGI. Plus I read various places that getting FastCGI to work can be hard.

Anonymous said...

Thats odd, both lighttpd and Django come ready to go for FastCGI. One of django-admin's arguments is for easily running the server using FastCGI/flup. I've had no problems at all.

Anonymous said...

I re-opened the ticket requesting native mod_wsgi support (or in mod_proxy) be added to lighttpd's module lineup, although I see myself looking more towards nginx as my apache replacement (using apache's mod_wsgi as a phase 1 stepping stone) as time goes on.

Anonymous said...

Forgot to add the relevant URL for those interested:

http://trac.lighttpd.net/trac/ticket/1523

:]

Manlio Perillo said...

For people interested, I have implemented a WSGI module for Nginx:
http://hg.mperillo.ath.cx/nginx/mod_wsgi/

At the moment it is only available via the Mercurial repository; the full documentation is in the README file.

Note that the module is still under development.

llothar said...

Does anybody know where i can find the django-scgi.py

The mentioned URL in the article is as dead as the guy's home page.

Google only returns 15 results for "django-scgi.py" but no location.

Post a Comment