toofishes.net

Git smart HTTP transport on nginx

Nine months ago, I set up the git smart HTTP transport on lighttpd and wrote a blog post about it because I didn’t see any documentation for non-Apache webservers. Turns out the same holds for nginx, which I switched to on my server due to some not so cool memory issues lighttpd has, especially on a memory-constrained VPS environment. More about that in another post.

I’ve figured out the magic needed to run git-http-backend behind nginx. It is trimmed down a bit from what I am actually running (e.g. no SSL, access_log stuff, etc.), but anything essential for the CGI service is still there.

Requirements

There is one additional requirement lighttpd did not have: you will need to install and have fcgiwrap installed and running. On Arch Linux, this just required a pacman -S fcgiwrap and then starting the service via the provided initscript.

The sample config assumes fcgiwrap is listening on localhost:9001 and your git repositories are rooted at /srv/git; adjust as necessary. The git repos will then be available at https://git.mydomain.com/git/myrepository.git.

Sample Configuration

http {
    ...
    server {
        listen       80;
        server_name  git.mydomain.com;

        location ~ /git(/.*) {
            # fcgiwrap is set up to listen on this host:port
            fastcgi_pass  localhost:9001;
            include       fastcgi_params;
            fastcgi_param SCRIPT_FILENAME     /usr/lib/git-core/git-http-backend;
            # export all repositories under GIT_PROJECT_ROOT
            fastcgi_param GIT_HTTP_EXPORT_ALL "";
            fastcgi_param GIT_PROJECT_ROOT    /srv/git;
            fastcgi_param PATH_INFO           $1;
        }
    }
}

Results and Testing

Obviously the above works for me or I would have nothing to write about. One thing that had me stumped for a little bit was the PATH_INFO bit- ensure the leading slash is present in the passed data, or you will get a 500 error with no error message to help you solve it. Originally I had the slash outside of the regex capture group, /git/(.*), instead of the correct /git(/.*).

The smart HTTP serving should be in place at a location like https://my.domain.com/git/myrepository.git. An easy way to check is to do a git clone on the HTTP URL of one of your repositories; if you see messages like remote: Counting objects: 722, done. then you have successfully set it up.

Tags

See Also