Publish GitWeb with Nginx Reverse-Proxying for Apache
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:
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
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>
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.