CVSweb with nginx

Whoever using FreeBSD, NetBSD, or OpenBSD must’ve at least once opened their respective online source repository browser – CVSweb. CVSweb is basically CVS version of hgwebdir and co – a web application to give CVS repository(ies) a web interface where one can browse the content of a CVS repository remotely without using command line. You can see CVSweb in action here (OpenBSD), here (NetBSD), and here (FreeBSD).

One day, I wanted to install CVSweb on one of my virtual machine. Instead of using Apache, I decided to try installing it using nginx. The obvious problem on installing CVSweb over nginx is nginx’s non-existent support for cgi. Well, for starter, cgi is considered slow, etc but it doesn’t help in this case.

Then we have fcgiwrap. Simply put, it’s a program which can be run to provide cgi support under fastcgi which nginx supports. Installing it is relatively easy and to run it you’ll need either the sample launcher provided in its website, spawn-fcgi, or supervisord. Note that under FreeBSD (and most likely anything other than Linux) you have to be, um, kind of creative – it uses autoconf and the configure will fail when searching for fastcgi library. There is a way to skip autoconf usage at all though. Simply fetch the fcgiwrap.c and compile it using this command:

cc -Wall -Werror -O2 fcgiwrap.c -o fcgiwrap -lfcgi -L/my/fcgi/lib -I/my/fcgi/include -static

The static option will allow you to remove fastcgi library from the system and still able to run fcgiwrap. Copy the compiled fcgiwrap somewhere you like and configure your fastcgi launcher. It looks like this under supervisord:


Adjust the paths, etc. Make sure not to run it under user root – you don’t want to take any risk.

Once the fcgiwrap set up correctly, you then need to install CVSweb. I’m not going to pretend anything here: I only know how to install it using (FreeBSD’s) ports. Manual install involves fulfilling dependencies which is not quite easy to do. It is available on Ubuntu and probably some other distros. After installation, locate and copy the cvsweb.cgi and the static data somewhere you like (I usually use /srv/http/cgi/cvsweb, btw). It goes something like this:

  • cvsweb.cgi (and its config – cvsweb.conf): /srv/http/cgi/cvsweb/root
  • css, icons: /srv/http/cgi/cvsweb/public

Before continuing to nginx config, please rename and move cvsweb.cgi to wherever and whatever name you want relative to the CVSweb path you want for the address. Examples:

  • rename to cvsweb
  • put cvsweb.cgi in /srv/http/cgi/cvsweb/root/cgi-bin/
  • rename cvsweb.cgi to where and put in /srv/http/cgi/cvsweb/root/some/

You get the idea.

After that, it’s relatively simple in nginx:

  location = /cvsweb {
    rewrite ^ /cvsweb/ permanent;
  location /cvsweb/ {
    alias /srv/http/cgi/cvsweb/public/;
    try_files $uri @cvsweb;
  location @cvsweb {
    include fastcgi_params;
    fastcgi_pass unix:/tmp/fcgiwrap.sock;
    root /srv/http/cgi/cvsweb/root;

And done.

Or better, use ViewVC instead of CVSweb and proxy nginx to its standalone server.

Leave a Reply

Your email address will not be published. Required fields are marked *