Serving Mercurial repositories with Apache and mod_wsgi

TableOfContents

1. Introduction

[http://code.google.com/p/modwsgi/ mod_wsgi] is a simple to use Apache module which can host any Python application which supports the Python WSGI interface (such as slightly modified hgwebdir.cgi). It can be run as "in server" process (just like mod_python), or in "daemon mode" (equivalent to FastCGI).

Please don't blindly follow this document. At least read official [http://code.google.com/p/modwsgi/w/list mod_wsgi documentation] (it's pretty good), and PublishingRepositories. It is expected that you know how to properly configure Apache :-D

1.1. Advantages

1.2. Disadvantages

2. Pre-requisites

You'll need following software (tested versions are in parenthesis, other versions should work too):

3. Configuration

3.1. mod_wsgi

In case you can't find mod_wsgi package for your operating system, you'll have to compile it yourself.

e.g.

$ tar xvf mod_wsgi-1.1.tar.gz
$ cd mod_wsgi-1.1
$ ./configure
$ make
$ su -c "make install"

Edit your httpd.conf file to load wsgi module:

LoadModule wsgi_module libexec/httpd/mod_wsgi.so

3.2. Apache

In this sample setup, we are serving mercurial repositories from separate virtual host (hg.example.net). Repositories are in htdocs directory, served by modified hgwebdir.cgi script (hgwebdir.wsgi).

<VirtualHost *:80>
    ServerName hg.example.net
    DocumentRoot /var/www/vhosts/hg.example.net/htdocs
    ErrorLog /var/log/httpd/hg.example.net-error_log
    CustomLog /var/log/httpd/hg.example.net-access_log common

    WSGIScriptAliasMatch ^(.*) /var/www/vhosts/hg.example.net/cgi-bin/hgwebdir.wsgi$1

    # To enable "daemon" mode, uncomment following lines. (Read mod_wsgi docs for more info)
    # WSGIDaemonProcess hg.example.net user=USER group=GROUP threads=15 maximum-requests=1000
    # WSGIProcessGroup hg.example.net

    <Directory /var/www/vhosts/hg.example.net/htdocs>
        Options FollowSymlinks
        DirectoryIndex index.html

        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

    <Directory /var/www/vhosts/hg.example.net/cgi-bin>
        Options ExecCGI FollowSymlinks
        AddHandler cgi-script .cgi

        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

3.3. Mercurial

You only need to change the last line in hgwebdir.cgi script which comes with mercurial. Here is the short version - hgwebdir.wsgi:

   1 #!/usr/bin/env python
   2 
   3 from mercurial.hgweb.hgwebdir_mod import hgwebdir
   4 from mercurial.hgweb.request import wsgiapplication
   5 
   6 def make_web_app():
   7     return hgwebdir("hgwebdir.config")
   8 
   9 application = wsgiapplication(make_web_app)

Where hgwebdir.config file looks like this:

[web]
style = gitweb

[collections]
/var/www/vhosts/hg.example.net/htdocs = /var/www/vhosts/hg.example.net/htdocs

4. Note

It seems to me that mod_wsgi is the future of python web applications on Apache. It really nice, even in this early stage, and I expect it to become even better.

Bye mod_python/fastcgi, you won't be missed.