common Weblog

the weblog of François Chavant, Raphaël Vinot and Lucas Pinto

Gitweb with gitosis & nginx HowTo

Posted by François Chavant Sat, 30 May 2009 19:30:00 GMT
This quick howto describes how I got gitweb working with gitosis repositories and the nginx web server.


Nginx is a free, open-source, high-performance HTTP server and reverse proxy. Gitosis aims to make hosting git repositories easier and safer.

Note: I used Debian (lenny) but this howto should work on any distribution with minor changes.

gitweb


First we'll need to configure gitweb. Its configuration file is named gitweb.conf and is located in /etc under debian.
The file should be self explanatory:

# /etc/gitweb.conf
$stylesheet = "/static/gitweb.css"; $logo = "/static/git-logo.png"; $favicon = "/static/git-favicon.png"; # Point to projects.list file generated by gitosis. $projects_list = "/srv/gitosis/gitosis/projects.list"; # Where the actual repositories are located. $projectroot = "/srv/gitosis/repositories"; # By default, gitweb will happily let people browse any repository # they guess the name of. This may or may not be what you want. # I prefer to set these, to allow exactly the repositories in # projects.list to be browsed. $export_ok = ""; $strict_export = "true"; # A list of base urls where all the repositories can be cloned from. # Easier than having per-repository cloneurl files. @git_base_url_list = ('git+ssh://gitosis@git.chavant.info');


gitosis


Next we will configure gitosis so that it generates the list of browseable repositories (/srv/gitosis/gitosis/projects.list) we specified in gitweb.conf.
In your gitosis-admin/gitosis.conf, you will need to add a block for each browseable repository, just like this one:

# gitosis.conf (excerpt)
... [repo foo] gitweb = yes owner = John Doe description = foo repository ...

Again these parameters should be quite self explanatory.


nginx configuration


Here is the relevant part of my nginx config:

# /etc/nginx/nginx.conf (excerpt)
server { listen 66.71.241.174:80; server_name git.chavant.info; access_log /var/log/nginx/git.access.log; error_log /var/log/nginx/git.error.log; location / { fastcgi_pass 127.0.0.1:7000; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; } location /static { root /home/gitosis/gitweb; }

nginx simply acts as a reverse proxy to 127.0.0.1 on port 7000 (this is arbitrary)

FastCGI


Gitweb is a Perl CGI but nginx only supports FastCGI, so let's use a simple Perl wrapper. (This script is from a patch by Eric Wong sent on the git mailing list)

#!/usr/bin/perl -w

use strict;
use FCGI;
use CGI;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;

sub usage {
       print STDERR "$0 --fcgi-socket=(path|[host]:port) ",
                    "--cgi-bin=path\n";
       exit 1;
}

my ($fcgi_sock, $cgi_bin);
GetOptions('fcgi-socket|s=s' => \$fcgi_sock,
           'cgi-bin|c=s' => \$cgi_bin) or usage();

usage() unless ($fcgi_sock && $cgi_bin);

die "FastCGI socket: $fcgi_sock already exists!\n" if (-S $fcgi_sock);
die "CGI executable: $cgi_bin does not exist!\n" if (!-f $cgi_bin);

# gitweb will exit, make it throw an exception instead:
no warnings qw/once/;
*CORE::GLOBAL::exit = sub { die 'gitweb_exit' };
use warnings;

# FCGI will erase the current %ENV; so make sure we save this:
my $gwcfg = $ENV{GITWEB_CONFIG};

my $fcgi_req = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
                             FCGI::OpenSocket($fcgi_sock, 128),
                             FCGI::FAIL_ACCEPT_ON_INTR);
while ($fcgi_req->Accept >= 0) {
       unless ($ENV{PATH_INFO}) {
               # nginx currently fails to set PATH_INFO,
               # so we'll do it ourselves
               my $pi = $ENV{SCRIPT_NAME};
               $pi =~ s!^/\+!!;
               $ENV{PATH_INFO} = $pi;
       }
       # clear CGI query parameters set inside gitweb so we can reparse
       # the %ENV fed to us
       CGI::initialize_globals();
       $ENV{GITWEB_CONFIG} = $gwcfg if defined $gwcfg;
       do $cgi_bin;
       delete $ENV{PATH_INFO};
}

END {
       unlink $fcgi_sock if (defined $fcgi_sock && -S $fcgi_sock);
}

We then execute this wrapper in the background and we are done.

su gitosis -c /home/gitosis/gitweb/gitweb.fcgi \   --fcgi-socket=127.0.0.1:7000 \   --cgi-bin=/usr/lib/cgi-bin/gitweb.cgi &
Note that gitosis is the user account under gitosis runs and /usr/lib/cgi-bin/gitweb.cgi is the default path of the Gitweb CGI under Debian.


You should now be able to use Gitweb via nginx to browse (some of) your gitosis repositories.

Posted in | 2 comments |

Trackbacks

Use the following link to trackback from your own site:
http://blog.chavant.info/trackbacks?article_id=6

Comments

Leave a comment

  1. Mark
    10 months later:

    Thanks a lot for your detailed instructions. Helped me getting gitweb upand running some months ago.

    Unfortunately now I receive this error messages, rendering gitweb useless after the second request:

    2010/03/13 15:04:30 [error] 19710#0: *49 FastCGI sent in stderr: "2010] gitweb.fcgi: Subroutine git_blame_data redefined at /usr/share/git/gitweb/gitweb.cgi line 5240.
    [Sat Mar 13 15:04:30 2010] gitweb.fcgi: Subroutine git_tags redefined at /usr/share/git/gitweb/gitweb.cgi line 5244.
    [Sat Mar 13 15:04:30 2010] gitweb.fcgi: Subroutine git_heads redefined at /usr/share/git/gitweb/gitweb.cgi line 5257.
    [Sat Mar 13 15:04:30 2010] gitweb.fcgi: Subroutine git_blob_plain redefined at /usr/share/git/gitweb/gitweb.cgi line 5270.
    [Sat Mar 13 15:04:30 2010] gitweb.fcgi: Subr" while reading response header from upstream, client: 192.168.1.2, server: git.ossdl.de, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:7000", host: "git.ossdl.de"

    Unluckily I cannot remember what I must have changed. Do you have a workaround?

  2. khanku
    10 months later:

    Hello,

    I never had such errors… But I recently switched to a newer version of gitweb (namely 1.7.x). This is basically just swapping the old gitweb.cgi in /usr/lib/cgi-bin/ with the new file. Maybe you could try this?

Leave a comment