Configuring Trac with FastCGI and lighttpd

I initially tried getting tracd to work, but couldn’t get it to generate URLs that made sense. So, I decided to investigate all the fuss about using lighttpd and FastCGI. It works, better than tracd likely, and is certainly more flexible.

Here’s my lighttpd.conf for dev.sabi.net. It essentially implements the “Global authentication” example from the TracMultipleProjects page on the Trac wiki. You need a trunk version of Trac for this to work; 0.8.x don’t have FastCGI support.

server.port         = 9013
server.document-root= "/home/nriley/web/public/"
server.indexfiles   = ( "index.html" )
server.pid-file     = "/home/nriley/var/run/lighttpd.pid"
server.errorlog     = "/home/nriley/logs/lighttpd.error.log"
accesslog.filename  = "/home/nriley/logs/lighttpd.access.log"
url.access-deny     = ( "~", ".inc" )
compress.cache-dir  = "/home/nriley/var/cache/lighttpd/compress/"
compress.filetype   = ( "text/plain", "text/html" )
fastcgi.server      = ( "/trac" =>
                       ( "trac" =>
                        ( "socket" => "/home/nriley/var/run/trac-fastcgi.sock",
                          "bin-path" => "/home/nriley/cgi-bin/trac.fcgi",
                          "bin-environment" =>
                           ( "TRAC_ENV_PARENT_DIR" => "/home/nriley/trac" )
                        )
                       )
                      )
alias.url           = ( "/media/" => "/home/nriley/share/trac/htdocs/" )
auth.backend        = "htdigest"
auth.backend.htdigest.userfile= "/home/nriley/etc/trac.digest.passwd"
$HTTP["url"] =~ "^/trac/[^/]+/login" {
    auth.require    = ( "/" =>
                       ( "method" => "digest",
                         "realm" => "sabi.net Subversion repository",
                         "require" => "user=nicholas"
                       )
                      )
}

In order for the above FastCGI association to work, I must create a file named trac in the server’s document root, so lighttpd has something to pass along to the FastCGI script. (I got this tidbit from this article on using Django with lighttpd).

I needed to use /media instead of /trac or something like /trac-common or /trac/common because I couldn’t get lighttpd to give up the FastCGI assocation with /trac.

It appears there’s nothing equivalent to “Require valid-user” in lighttpd, and the “require” statement isn’t parsed until a request is received, so you’ll need to add a bunch of users to a group and require a group, likely. The parsing error is very poorly identified, too: (http_auth.c.345) = is missing. I had to dig through the lighttpd source to see what it was referring to.

So, everything seemingly works; the only problem I’m having is my log file getting polluted with these messages:

2005-08-01 03:08:38: (mod_fastcgi.c.2110) FastCGI-stderr:  

which I’ve filed as a bug in Trac.

I also had to do some digging to figure out how to enable anonymous access to Subversion via WebDAV. The Subversion repository’s DAV interface was created as private to begin with, a sensible precaution. However, I couldn’t use <LimitExcept> to apply permissions, so instead I have a AuthzSVNAccessFile svn-access.conf that looks like this:

[dev:/]
nicholas = rw
* = r

Then I open up Apache access with Satisfy Any. Some more discussion of this technique is here.

svn.sabi.net → dev.sabi.net

svn.sabi.net is now dev.sabi.net (svn.sabi.net still works, too). I have by necessity removed some of the gimmicks such as the XML repository browser and ViewCVS, since my new web host doesn’t support the former, and Trac is much better than the latter. However, it’s no longer run from my desktop Mac and cable modem, and Trac is now using FastCGI/lighttpd instead of plain CGI/Apache, so the response time and throughput should be significantly improved.

For anyone who’s using one of the Subversion repositories, you will need to run svn switch on your working copies, as follows:

% svn switch --relocate http://svn.sabi.net/repos http://dev.sabi.net/svn

Unfortunately, Subversion does not understand HTTP redirection, and even the awesome power of mod_rewrite is not enough to save me. RewriteRule ^repos/(.+) /svn/$1 [R] gives me svn: PROPFIND of ‘/repos/dev/trunk/StreamVision’: 301 Moved Permanently (http://svn.sabi.net), making the redirection a permanent one doesn’t help, and simply rewriting gives me:

% svn up
svn: REPORT request failed on '/svn/dev/!svn/vcc/default'
svn:
Unusable URI: it does not refer to this repository

If you’re just using a Web browser to browse the repository, then you will be correctly redirected.

I’ve got some Apache/Trac/lighttpd configuration advice to share, but first I need to eat dinner…

Feeds fixed

WP-Cache 2.0, which caches the output of WordPress pages, broke the MIME types of my feeds, setting them to text/html; it’s still enabled for the non-XML pages I’m serving. This appears to be actually an Apache or PHP bug, but the workaround stands. And yes, I know this page doesn’t validate as XHTML at the moment; it will. I’ve temporarily changed the GUID/permalink format to include numbers, since otherwise there were many duplicate GUIDs for the ex-Radio entries that had no post titles.

Unlike it did last night, NetNewsWire appears to now correctly process the RSS 2.0 and Atom feeds. It may be because the Radio posts aged off the feed since I added the PyCS feeds in; regardless, I’m happy, and this is now my official weblog.

Hello Radio

This blog now includes posts from my Radio period, January 2002 through November 2003. I meant to migrate them to PyCS, but the barrier to entry was always a little too high. Not so with WordPress. Some links are broken, and I need to move the stories, but it’s a start at consolidation.

Sample post

Python [Show Plain Code]:
  1. def f(x):
  2.    return x

(the above brought to you courtesy of Syntax Highlighting with Enscript in WordPress Jay Tuley’s SyntHihol plugin).

Moved

As you may have noticed, I’m moving from PyCS/PyDS to WordPress. While there’s a certain amount of cachet to a weblog engine which likely numbers its users in the double digits, PyDS development is essentially dead, even the PyDS author is using WordPress for one of his weblogs, and I’d appreciate not having to manually deal with comment spam (and trackback spam, which I haven’t even explored).

All the posts from my PyDS and Radio weblogs have been imported, and are now searchable. Many thanks to Georg Bauer for his friendly help and migration scripts. The import process didn’t interpret macros (quoted strings) in the Radio posts, and there’s various other things I’ll have to fix up going forward, but it’s great to have a solid, supported, widely-used foundation on which to build.

250 feeds, neatly organized

In honor of subscribing to my 250th RSS/Atom feed today, I sorted my feeds into groups in NetNewsWire. The flat scrolling list was breaking down pretty badly at this size.

250 feeds, neatly organized

Sorting the feeds was a lot more effort than I expected, so I just finished submitting a bunch of bugs and feature requests (1 2 3 4 5 6, and some for the bug tracker itself: 7 8). Phew. Certainly, I hope 2.1 (or 2.5, or 3.0…) improves the process, but thankfully I won’t be having to sort everything from scratch ever again.

Some interesting tradeoffs in grouping feeds, which I hadn’t thought about before:

Only unread posts are shown for grouped feeds. This is rather nice, because normally you don’t care about the read posts.

There are several feeds (Wired News, RSS Weather, the New York Times, and some Trac feeds of fast-changing apps like Adium) which I hardly ever read; I typically scan the article titles, click something if it looks good, and otherwise hit “k” to mark everything as read and continue on my merry way. I’ve kept the weather feed ungrouped for this reason. You can’t do this when you’re reading an entire group of feeds; “k” will mark the entire group worth of articles as read.

My group titles are shorter than typical feed titles, so I can narrow the subscriptions list, and finally have more room for multiple columns in the news items table (to, among other things, display the selected source). However, with the “+” and gear buttons at the bottom of the list, many of the status messages which live at the bottom right get cut off.

Django is coming…

It’s time for another of those “I’m not dead” weblog posts; I’ve just been really busy writing papers.

However, I should have some time starting next week to get back to my other job, finishing some long-overdue Web work for the College of Medicine. I’m anxiously awaiting the release of Django, without a doubt the most exciting software I’ve seen all year. Yes, it’s “just” a Web framework, but it is astonishing in its simplicity, power and elegance. I stumbled upon the site today and it appears they’re shooting for a release this week.

Update: there’s mostly a site there now, and you can check out the BSD-licensed code from a Subversion repository, or of course there’s a Trac site. The code for the website is there, including what looks like a fully functional weblog engine. Must… resist…