Skip to content

Instantly share code, notes, and snippets.

@mcxiaoke
Created January 18, 2016 02:54
Show Gist options
  • Save mcxiaoke/055af99e86f8e8d3176e to your computer and use it in GitHub Desktop.
Save mcxiaoke/055af99e86f8e8d3176e to your computer and use it in GitHub Desktop.
Set up Gitweb + Nginx from scratch on Debian Wheezy

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.

Install

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

deb http://http.debian.net/debian 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 http://example.com:4321/
  listen 4321 default;   # Remove 'default' from this line if there is already another server running on port 80
  server_name example.com;

  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 http://example.com:4321/ 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 	
bdsatish.in        107.xx.yy.100    20000
www.bdsatish.in    107.xx.yy.100    20000

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

server {
    server_name  www.bdsatish.in;
    listen 80;
    rewrite ^(.*) http://bdsatish.in$1 permanent;
}

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

Troubleshooting

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

References

@1dotd4
Copy link

1dotd4 commented Jan 3, 2017

ls: cannot access '/var/run/fcgiwrap.socket': No such file

So I've created a service that spawn the socket look at the reference here

So the command to spawn the socket will be:
/usr/bin/spawn-fcgi -s /var/run/fcgiwrap.sock -P /var/run/fcgiwrap.pid -u www-data -g www-data -- /usr/sbin/fcgiwrap

After another error 502 I realised that I can't proxy /gitweb/

@jpartain89
Copy link

Actually, on the "Redirecting www to non-www" is an overly out-of-the-way means of handling that....

You simply have it as a second name in the server_name line...

server_name example.com www.example.com

And then, to force everything over to SSL/443, especially if you have multiple server blocks on the same machine, you don't have to change the port number that NGINX listens on. If the sites are simply proxies of the same parent, the parent divvies out the packets:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}
server {
    listen 443 default_server ssl http2;
    listen [::]:443 default_server ssl http2;
    server_name example.com www.example.com;
...
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name site.example.com www.site.example.com;
...
}

@m4l490n
Copy link

m4l490n commented Jan 25, 2019

And then, to force everything over to SSL/443, especially if you have multiple server blocks on the same machine, you don't have to change the port number that NGINX listens on. If the sites are simply proxies of the same parent, the parent divvies out the packets:

@jpartain89 how would I force everything over to SSL/443 if I don't have multiple server blocks?

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