Overview

Using Nginx as a reverse-proxy for Apache ensures that Apache is only used for dynamic content and the lighter Nginx web-server handles static content like images and css files.

Most installation guides for GitWeb assume that it will be hosted by a single web-server process (either Nginx or Apache). This article will show how to host GitWeb with Nginx acting as a front-end for Apache.

Assumptions

  • The Server OS is Debian/Lenny “stable”
  • Nginx is setup to listen for incoming connections on a publicly-accessible IP
  • Apache is configured to allow for multiple virtual hosts on the localhost IP

Nginx Compatability

For GitWeb to work correctly, the installed version of Nginx must support the try_files directive. Unfortuantely, the Debian “stable” version of Nginx (0.6.xx) does not. Hence, the Nginx install will need to be upgraded to 0.7.27 or higher. In Debian/Lenny, this can be easily accomplished with Backports - refer the Backports FAQ on adding backports to your sources.list file. Once that is done, the only command required is:

aptitude -t lenny-backports install nginx

Nginx Configuration

Add the following to your website configuration file under /etc/nginx/sites-available:

server {

            listen   my.ip.add.ress:80;
            server_name gitweb.domain.com;
            server_name_in_redirect off;

log_format domain_gitweb '$remote_addr - $remote_user [$time_local] $status '
                '"$request" $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

            access_log /var/log/nginx/gitweb-domain_access.log domain_gitweb;
            error_log /var/log/nginx/gitweb-domain-error.log;

    gzip  on;
    gzip_buffers 16 8k;
    gzip_min_length 0;
    gzip_proxied no-cache;
    gzip_types 	text/plain text/xml text/css
    		        text/comma-separated-values
    		        text/javascript application/x-javascript;
    gzip_disable     "MSIE [1-6]\.";
    gzip_comp_level 6;
						
	    ## Only allow GET and HEAD request methods
            if ($request_method !~ ^(GET|HEAD)$ ) {
                        return 444;
                        }
						
            root   /usr/share/gitweb;
            #root has to be moved outside any location directives, otherwise adding expire headers
            #will break

        location / {
                         try_files $uri @gitweb;
                        }
						
	location ~* ^.+\.(jpg|jpeg|gif|png|html)$ {
                                  expires 30d;
                }
						                         
        location ~* ^.+\.(css|js)$ {
                expires 30d;
                gzip_vary on;
            }
            
        location @gitweb {
            			rewrite ([^/]+)/(.*)  /gitweb.cgi/$1 break;
            			rewrite ^(/)$ /gitweb.cgi last;
           			
		        }
	#End Rewrites
						
	#Pass to Apache										
            location ~* ^.*\.cgi(.*) {
    	        proxy_set_header X-Real-IP  $remote_addr;
    	        proxy_set_header Host $host;
    	        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    	        proxy_pass http://127.0.0.1:80;
	    }

	}

Explaining the Nginx Configuration

Some of the core parameters that affect the setup are explained below:

Paramter Explanation
server_name gitweb.domain.com; The rest of the configuration assumes GitWeb is being served from a subdomain. If Gitweb is being hosted at domain.com/gitweb, then the ”/” and ”@gitweb” location directives will need to be modified accordingly
location / {try_files $uri @gitweb;} This instructs Nginx to try and serve the requested resource from the path specified in the root directive, or else transfer processing to the “gitweb” location

Apache Configuration

Add The following to the site configuration file in /etc/apache2/sites-available:

<VirtualHost 127.0.0.1>
        ServerName gitweb.domain.com
        ServerAdmin webmaster@domain.com
        LogLevel warn
        ErrorLog /var/log/apache2/gitweb-domain_com-error.log
        DeflateFilterNote Input input_info
        DeflateFilterNote Output output_info
        DeflateFilterNote ratio_info
        LogFormat '%h %t "%r" %{input_info}n/%{output_info}n (%{ratio_info}n%%)' compressed
        CustomLog /var/log/apache2/gitweb-domain-access.log combined
        CustomLog /var/log/apache2/gitweb-domain-deflate.log compressed

       DocumentRoot /usr/lib/cgi-bin/
        #Compression Directives
        AddOutputFilterByType DEFLATE application/x-perl
        #Additional Compression Directives
        BrowserMatch \bMSIE\s(7|8) !no-gzip !gzip-only-text/html #This will need to be modified  everytime a new IE version is released
        #Following Directives ensure mod_deflate is not used for binary file types
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.avi$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.mov$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.mp4$ no-gzip dont-vary
        SetEnvIfNoCase Request_URI \.rm$ no-gzip dont-vary

          <Directory /usr/lib/cgi-bin/>
          AllowOverride AuthConfig
          Order allow,deny
          Allow from all
          Options +ExecCGI +Indexes
          DirectoryIndex gitweb.cgi
          SetEnv GITWEB_CONFIG "/etc/gitweb.conf"
          AddType application/x-perl .cgi
          AddHandler cgi-script .cgi
          RewriteEngine On
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^.* /gitweb.cgi/$0 [L,PT]
          </Directory>

</VirtualHost>

Explaining the Apache Configuration

Much of the configuration here is directly from the GitWeb README. The only additional directives here pertains to gzip compression of the output, i.e.:

Paramter Explanation
AddType application/x-perl .cgi The default mime.types file that Apache uses does not recognize cgi files. This adds a handle for the cgi files and activates gzip compression (all settings defaulted) for the output
AddHandler cgi-script .cgi
AddOutputFilterByType DEFLATE application/x-perl

Testing the configuration

Reload Nginx and Apache and then navigate to gitweb.domain.com. The familiar GitWeb page should come up. You can see a working example of this setup on my Git repositories page


Navigation