Skip to content

Instantly share code, notes, and snippets.

Last active Aug 29, 2015
What would you like to do?

This guide offers the least time-consuming way of setting up Nginx for serving Git repositories over HTTP using Gitweb. The stuff here has been tested with Git 1.9.1 and Nginx 1.6.0 on Debian Wheezy. Probably also works for Ubuntu, etc.

Total time ~ 10 minutes.


Enable wheezy-backports by adding this line to /etc/apt/sources.list:

deb wheezy-backports main

Warning: Upstream Nginx devs also offer packages for wheezy, but requires more tweaking than the one from backports. So, the following assumes nginx from backports.

apt-get install -t wheezy-backports nginx nginx-common git gitweb fcgiwrap

Configuration files you need to know about (we won't edit any of them, just fyi):

  1. /etc/gitweb.conf defines the root dir of your Git repos. By default it is /var/lib/git/.
  2. /usr/share/gitweb contains index.cgi script that is loaded when you visit through a web browser.
  3. /etc/nginx/nginx.conf -- just check that the user (first line) is www-data and not nginx
  4. /etc/nginx/sites-available/default is the default config of your webserver.
  5. /var/run/fcgiwrap.socket is the socket through which FastCGI and Nginx communicate.

In case you run into errors, check Nginx logs /var/log/nginx/error.log and /var/log/nginx/access.log.

Configure Nginx

Nginx works such that it can serve multiple websites at same time. The available sites are in a sites-available folder. We can selectively enable the sites by symlinking from sites-available to sites-enabled.

Since port 80 is probably already in use by the default website on your server, we'll use another port 4321 to serve our Git repos. Create a new file /etc/nginx/sites-available/gitweb with contents:

server {
  # Git repos are browsable at
  listen 4321 default;   # Remove 'default' from this line if there is already another server running on port 80

  location /index.cgi {
    root /usr/share/gitweb/;
    include fastcgi_params;
    gzip off;
    fastcgi_param SCRIPT_NAME $uri;
    fastcgi_param GITWEB_CONFIG /etc/gitweb.conf;
    fastcgi_pass  unix:/var/run/fcgiwrap.socket;

  location / {
    root /usr/share/gitweb/;
    index index.cgi;

Now, enable it:

ln -s /etc/nginx/sites-available/gitweb /etc/nginx/sites-enabled/gitweb
service nginx restart

Point your browser to and you should see a complaint about "No projects found".

Importing repos

The simplest way is to symlink the .git folder of some existing repo.

ln -s /home/$USER/.emacs.d/.git /var/lib/git/emacs.git

Refresh the projects page and it should show up. If it doesn't try:

cd /var/lib/git
git clone --bare /home/$USER/.emacs.d/.git emacs.git
cd emacs.git
cp hooks/post-update.sample hooks/post-update
chmod a+x hooks/post-update

Also remember to edit the the description file /var/lib/git/emacs.git/description and put in a couple of lines describing your project. These contents show up in the Gitweb's description column.

Restart server and it should all be ok now. (If not, meh, leave a comment below.)

Optional tweaks

You can uncomment these lines in /etc/gitweb.conf:

# file with project list; by default, simply scan the projectroot dir.
$projects_list = $projectroot;

# stylesheet to use
@stylesheets = ("static/gitweb.css");

# javascript code for gitweb
$javascript = "static/gitweb.js";

Redirecting www to non-www

Just add an "A record" to your DNS config, pointing to the same IP address as the non-www

Domain              IP Address       TTL        107.xx.yy.100    20000    107.xx.yy.100    20000

Then add the following at the beginning of /etc/nginx/sites-available/default for HTTP

server {
    listen 80;
    rewrite ^(.*)$1 permanent;

You can then use wget or curl -L to see if they return the same webpage as their non-www counterpart. Also, curl -I will show in the HTTP header that it has "Moved permanently".


If you see ngingx error.log say something like

connect() to unix:/var/run/fcgiwrap.socket failed (13: Permission denied) while connecting

then check the owner:group of /var/run/fcgiwrap.socket (it should be www-data:www-data). If not, just restart FCGIwrap:

service nginx stop
service fcgiwrap restart
service nginx start


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment