Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I've tried this in many different ways. Here is probably the best configuration I've managed to come up with.


server {
    server_name   git.domain.com;
    access_log   /var/log/nginx/git.domain.com-access.log;
    error_log   /var/log/nginx/git.domain.com-error.log;

    include common;

    location / {
        fastcgi_pass   unix:/var/run/fcgiwrap.socket;

        # fastcgi_param   DOCUMENT_ROOT   /home/yuri/git;
        # fastcgi_param   SCRIPT_NAME   /1.pl;
        fastcgi_param   DOCUMENT_ROOT   /usr/lib/git-core;
        fastcgi_param   SCRIPT_NAME   /git-http-backend;
        include fastcgi_params;
        fastcgi_param   DOCUMENT_ROOT   /home/yuri/git;

        fastcgi_param   GIT_HTTP_EXPORT_ALL   "";
        fastcgi_param   GIT_PROJECT_ROOT   /home/yuri/git;
        fastcgi_param   PATH_INFO   $request_uri;

I've written a little script to intercept data between fcgiwrap and git-http-backend. Here it is:

use Data::Dumper;
my $output = `/usr/lib/git-core/git-http-backend`;
open my $fh, '>', '/home/yuri/git/1/1.txt';
print $fh $output;
print $output;

And here is the output I get:

$ git clone http://git.domain.com/1.git
Cloning into '1'...
fatal: http://git.domain.com/1.git/info/refs?service=git-upload-pack not found: did you run git update-server-info on the server?

Apparently, I did run git update-server-info. Because for example I can clone this repository without git-http-backend:

server {
    server_name   git.domain.com;
    root   /home/yuri/git;

And here is the data I get in 1.txt:

Status: 404 Not Found^M
Expires: Fri, 01 Jan 1980 00:00:00 GMT^M
Pragma: no-cache^M
Cache-Control: no-cache, max-age=0, must-revalidate^M
$VAR1 = {
          'SERVER_NAME' => 'git.domain.com',
          'SCRIPT_NAME' => '/1.git/info/refs',
          'CONTENT_LENGTH' => '',
          'REQUEST_METHOD' => 'GET',
          'SERVER_SOFTWARE' => 'nginx/0.7.67',
          'REMOTE_PORT' => '53908',
          'QUERY_STRING' => 'service=git-upload-pack',
          'SERVER_PORT' => '80',
          'REDIRECT_STATUS' => '200',
          'REMOTE_ADDR' => 'x.x.x.x',
          'CONTENT_TYPE' => '',
          'SERVER_PROTOCOL' => 'HTTP/1.1',
          'DOCUMENT_URI' => '/1.git/info/refs',
          'REQUEST_URI' => '/1.git/info/refs?service=git-upload-pack',
          'GATEWAY_INTERFACE' => 'CGI/1.1',
          'SERVER_ADDR' => 'x.x.x.x',
          'DOCUMENT_ROOT' => '/home/yuri/git'

I'm running Debian squeeze, fcgiwrap-1.0, git-, nginx-0.7.67.

UPD I would be grateful if someone could at least provide me with the output of my script under apache?

On a side note, this version of fcgiwrap ignores SCRIPT_FILENAME. DOCUMENT_ROOT and SCRIPT_NAME are concatenated and split back again into the script name and PATH_INFO. But the first fastcgi_param DOCUMENT_ROOT must point to the right location, otherwise fcgiwrap wouldn't find the script to be launched for some reason. That is, this doesn't work:

        fastcgi_param   DOCUMENT_ROOT   $document_root;   # /usr/local/nginx/html
        fastcgi_param   DOCUMENT_ROOT   /home/yuri/git;

But this works:

        fastcgi_param   DOCUMENT_ROOT   /home/yuri/git;
        fastcgi_param   DOCUMENT_ROOT   $document_root;   # /usr/local/nginx/html

That is the reason behind slightly obscure nginx configuration:

        fastcgi_param   DOCUMENT_ROOT   /usr/lib/git-core;
        include fastcgi_params;
        fastcgi_param   DOCUMENT_ROOT   /home/yuri/git;

But there are some setups when it works...

share|improve this question
Aside, you have your host name visible in the top server_name. –  Lekensteyn May 29 '13 at 9:31
Oh, thanks for your remark :) though, it's password-protected... –  x-yuri May 29 '13 at 12:35
@Lekensteyn, I can't comment your answer, so... First off, I have fcgiwrap-1.0-1+squeeze1 and it ignores SCRIPT_FILENAME. You can see it by inspecting commit history of v1.0.1 and v1.0.2. Anyway, I've checked it with the following nginx config and the following test script. –  x-yuri May 30 '13 at 17:20
I decided to make order of fastcgi_param a separate question. –  x-yuri May 30 '13 at 18:22
I am using a development version containing a patch for a way to restrict executable files on Wheezy. I knew the squeeze one was buggy, so I never bothered trying that one. Hey, it is a single executable anyway. –  Lekensteyn May 30 '13 at 22:33

2 Answers 2

DOCUMENT_ROOT + SCRIPT_NAME cannot be combined with PATH_INFO. Use an absolute SCRIPT_FILENAME instead (since your git-http-backend program is located out of your document root).

As a debugging hint, to test whether smart HTTP works, look at your access logs.

The following configuration is tested on Debian 7.0 Wheezy:

# based on http-backend.c from git v1.8.2.1, service_cmd
location ~ "^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$" {
    fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
    fastcgi_param GIT_PROJECT_ROOT /home/yuri/git;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    include fastcgi_params;
    fastcgi_pass unix:/var/run/fcgi-wrap.sock;

Adding options like GIT_HTTP_EXPORT_ALL is an exercise for the reader.

share|improve this answer
Still doesn't work, here are the nginx config, shell output and perl-script output. By the way, PATH_INFO doesn't get passed, as opposed to PATH_INFO2 e.g. Could you tell what you're getting (when it works, of course)? –  x-yuri Jun 1 '13 at 11:24
@x-yuri, since it seems a personal server, can you upgrade from Squeeze to Wheezy to make your software more up-to-date? What does fastcgi_params contain? Mine is at fpaste.org/15991 –  Lekensteyn Jun 1 '13 at 13:39
Actually it's a production server :) And well I can install wheezy on my PC, but that would take time. And I'd be grateful if you'd tell what environment of CGI process is when it works. Because that's what I guess is causing the problems. My fastcgi_params is like this. –  x-yuri Jun 4 '13 at 12:57
@x-yuri You mentioned that SCRIPT_FILENAME gets ignored with your fcgiwrap version. I strongly recommend you upgrading fcgiwrap to a more recent version where this is fixed if you are unable to upgrade to Wheezy. This also holds for production environments. –  Lekensteyn Jun 4 '13 at 13:09
Lekensteyn: I just tested your config on a vanilla wheezy installation and it worked after two minor changes: - changed /var/run/fcgi-wrap.sock to /var/run/fcgiwrap.socket (the default on wheezy) - installed git 1.8.x from wheezy-backports. git 1.7 refused to work for some reason. Thanks for your help. –  Luca G. Mar 21 '14 at 14:16
up vote 0 down vote accepted

The problem it didn't work was that PATH_INFO wasn't set correctly. Since "DOCUMENT_ROOT and SCRIPT_NAME are concatenated and split back again into the script name and PATH_INFO". This is the configuration that works:

server {
    server_name   domain.com;
    root   /home/yuri/git;
    access_log   /var/log/nginx/domain.com-access.log;
    error_log   /var/log/nginx/domain.com-error.log;

    location / {
        fastcgi_pass   unix:/var/run/fcgiwrap.socket;

        fastcgi_param   DOCUMENT_ROOT   /usr/lib/git-core;
        fastcgi_param   SCRIPT_NAME   /git-http-backend$fastcgi_script_name;
        include   fastcgi_params;

        fastcgi_param   GIT_HTTP_EXPORT_ALL   "";
        fastcgi_param   GIT_PROJECT_ROOT   /home/yuri/git;

Then you can clone repositories like this:

git clone http://domain.com/1.git

where 1.git is located in /home/yuri/git.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.