Lfborjas' Nerdlog

Hosting a fossil repo with lighttpd

I started working in a project, and it was using fossil as it’s scm. I cloned it and began doing my stuff, at first it felt weird, as I am a git user, but eventually I got the knack of it and it feels nice and clean, definitely easier than git. However, because I’m not part of the official project (i.e. I’m working on a fork, if you wanna hear git-speak), I didn’t have write privileges on the server, so I decided to host my own copy.

I’m running a personal git server with lighttpd, so I decided that I’d use another virtual host under the same domain for the fossil repo. I’m fairly ignorant of lighttpd and web server technologies in general, so I ran into a wall when trying to host the fossil repo using the cgi script. I didn’t want to give up and just run fossil server, because it would be ugly to write the ip:port combo everytime and because I didn’t want to waste my limited memory in a long running daemon. So I set up the virtual host and configured it to relay control to the cgi script, but it only worked for the root url ("/"). But it didn’t work (I’m guessing now that leaving the field blank would have done the job…) At the moment, I was, nevertheless, stumped, so I asked in serverfault and left it there.

After that a whole month went by and I kinda forgot the whole thing, as I paused my work in the project to attend to more urgent matters. A couple of days ago, however, I got an answer to my serverfault question which suggested that I use mod_proxy with the fossil server command. And after reading a little more, both this article by Zed Shaw and the actual manual, it hit me: run it as a xinetd service in some port and use mod_proxy to direct requests to the subdomain to it. So here’s what I did:

  1. Installed xinetd (sudo apt-get install xinetd)
  2. Created a user for the project (sudo useradd -m theuser)
  3. Moved the fossil file (the sqlite db) to that user’s home folder and set him as owner and group.
  4. Added a new xinetd service (under /etc/xinetd.d) to listen for http requests in the port 8081.
  5. Added a new lighty virtual host that used proxy to redirect all its requests to the port 8081.
  6. Restarted xinetd and lighty and voilà, things worked.

One caveat with this approach is that, in the lighttpd conf, when setting up the proxy the first time, I wrote the loopback address (, but that made fossil believe that it was a local request, and it logged me in automatically. Because the site is publicly accessible, that’s not good at all. The solution was to write the host’s actual public ip address in the proxy config.

The xinetd service, which I put in /etc/xinetd.d/fossil, looks something like this (I got the idea from here):

service fossil
    type = UNLISTED
    port = 8081
    socket_type = stream
    protocol = tcp
    user = root
    wait = no
    cps = 1000
    server = /usr/bin/fossil
    server_args = http /home/theuser/fossils/project.fossil

And the important parts of the lighty conf file (in /etc/lighttpd/lighttpd.conf) look like this (and this bit was inspired by this web2py recipe):

server.modules  = (
            #other irrelevant modules 

#more conf...
$HTTP["host"] =~ "^the-subdomain.the-domain.com$" {
  proxy.server = (
    #"" matches ALL paths, like a wildcard
    "" => ((
     "host" => "", #this is not the actual ip address
     "port" => 8081
blog comments powered by Disqus