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.