Version Control With Git, Access Control With Gitolite, and Authenticated Web Repository Viewing With Gitweb + Apache on Ubuntu 11.04 Server

Phew, that’s a long title.
This post aims to start with a fresh install of Ubuntu 11.04 Server, installing git, gitolite, apache, and gitweb in order to do version control with access control and a web-based repository viewer. If you’re not running Ubuntu 11.04, most of this guide should still apply.

Assumptions

Here’s a list of (hopefully) not too restrictive assumptions this post makes:

  • You have full root shell access on the server you’re working with
  • Your git repos will be stored in /home/git, and the git repos will be managed by a user named “git”
  • You already have public/private SSH key authentication set up
  • You’re OK with using apache’s htpasswd method for authenticating access to gitweb
  • I’ll be using “example.com” to represent your domain name. If you don’t have a domain name, you’ll have to use the subdirectory method when configuring apache
  • I’ll also be using “you” as your user name. Replace this with your actual user name

Any commands this guide uses that require root privileges will be preceded by “sudo.”

Git

First, you’ll want to install git and do the initial configuration:

sudo apt-get install git
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Gitolite

It is possible to install gitolite using apt, but I decided to get the latest version from the gitolite repository.
First, copy your public key (usually ~/.ssh/id_dsa.pub) from your local computer to /tmp/you.pub on your server.
Download and install gitolite (this process is identical to the root method on the gitolite site). You’ll be creating the “git” user along the way.

# Clone the repo
git clone git://github.com/sitaramc/gitolite
cd gitolite
# Install gitolite
sudo src/gl-system-install
# Create the git user (if you don't already have one)
# with its own group and home directory at /home/git
sudo useradd -d /home/git -m -U git
# Become that user
sudo su - git
# Do the initial setup with your public key
gl-setup /tmp/you.pub

Gitolite will now prompt you with its config file, asking you to change any variables you want. The important variables to change are:

# Set this to 1 if you want to use wildcard repository names
$GL_WILDREPOS = 1;
# Equivalent to rwxr-x--- permissions - you'll want apache
# to be able to read the repos (you'll add it to the git
# group later)
$REPO_UMASK = 0027;
# Apache htpasswd file
$HTPASSWD_FILE = "/home/git/htpasswd";

On your local machine, you can check out a copy of the gitolite-admin repository:

git clone git@example.com:gitolite-admin.git

Take a look at the config file (gitolite-admin/conf/gitolite.conf). By default, it has a user configured for you based on the name of your public key. To add new users, add their key to gitolite-admin/keydir (making sure to git add the file) and commit. The default config has the admin repo and a testing repo and looks like this:

repo    gitolite-admin
        RW+     =   you

repo    testing
        RW+     =   @all

I won’t go into detail of configuring repositories here. For more information, check the official documentation. Once you’ve changed the config to your liking, make sure to commit and push:

git commit -am 'Made initial changes to the admin repo'
git push

Installing Apache

At this point, you’ll need to install apache. You’ll be configuring it later.

sudo apt-get install apache2

You’ll also want to add the apache user to the git group, and give it write permission to the /home/git/.gitolite folder (otherwise gitweb will throw an error later on):

sudo usermod -a -G git www-data
sudo chmod -R 770 /home/git/.gitolite

Also, create the htpasswd file used in the gitolite config earlier:

sudo -u git touch /home/git/htpasswd

At this point, from your local machine, you can also create your password in the htpasswd file. Thankfully, gitolite provides a simple way for you to do this:

ssh git@example.com htpasswd

Gitweb

I installed gitweb using apt:

sudo apt-get install gitweb

You’ll now need to customize the gitweb config (/etc/gitweb.conf). The gitolite docs show how to do this. Here’s what my config looks like (the (hopefully) only line you might have to change is highlighted):

# --------------------------------------------
# Per-repo authorization based on gitolite ACL
# Include this in gitweb.conf
# See doc/3-faq-tips-etc.mkd for more info

# please note that the author does not have personal experience with gitweb
# and does not use it.  Some testing may be required.  Patches welcome but
# please make sure they are tested against a "github" version of gitolite
# and not an RPM or a DEB, for obvious reasons.

# HOME of the gitolite user
my $gl_home = $ENV{HOME} = "/home/git";

# the following variables are needed by gitolite; please edit before using

# this should normally not be anything else
$ENV{GL_RC} = "$gl_home/.gitolite.rc";

# this can have different values depending on how you installed.
$ENV{GL_BINDIR} = "/usr/local/bin";

# finally the user name
$ENV{GL_USER} = $cgi->remote_user || "gitweb";

# now get gitolite stuff in...
unshift @INC, $ENV{GL_BINDIR};
require gitolite_rc;    gitolite_rc -> import;
require gitolite;       gitolite    -> import;

# set project root etc. absolute paths
$ENV{GL_REPO_BASE_ABS} = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$gl_home/$REPO_BASE" );
$projects_list = $projectroot = $ENV{GL_REPO_BASE_ABS};

$export_auth_hook = sub {
    my $repo = shift;
    # gitweb passes us the full repo path; so we strip the beginning
    # and the end, to get the repo name as it is specified in gitolite conf
    return unless $repo =~ s/^\Q$projectroot\E\/?(.+)\.git$/$1/;

    # check for (at least) "R" permission
    my ($perm, $creator) = &repo_rights($repo);
    return ($perm =~ /R/);
};

###############################
# ORIGINAL GITWEB CONFIG FILE #
###############################
# path to git projects (<project>.git)
#$projectroot = "/home/git/repositories";

# directory to use for temp files
$git_temp = "/tmp";

# target of the home link on top of all pages
#$home_link = $my_uri || "/";

# html text to include at home page
#$home_text = "indextext.html";

# 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";

# logo to use
#$logo = "static/git-logo.png";

# the 'favicon'
#$favicon = "static/git-favicon.png";

# git-diff-tree(1) options to use for generated patches
#@diff_opts = ("-M");
@diff_opts = ();

Configuring Apache

When configuring apache, you can either install gitweb as a subdirectory (example.com/git) or a subdomain (git.example.com). I’ll cover both methods.

Subdirectory Method

In your apache config file (probably /etc/apache2/sites-enabled/000-default if you just installed apache), insert the highlighted lines (my entire default config file is provided for context):

<VirtualHost *:80>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        Alias /git /usr/share/gitweb
        <Directory "/usr/share/gitweb">
           Options ExecCGI
           DirectoryIndex gitweb.cgi

           AuthType Basic
           AuthName "Gitweb"
           AuthUserFile /home/git/htpasswd
           Require valid-user
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>

Now, reload apache:

sudo service apache2 restart

and you should be able to login using your username and password you set up earlier by going to http://example.com/git.

Virtual Host Method

You’ll want to create a new config file to contain the virtual host (for example, /etc/apache2/sites-enabled/001-gitweb). Fill that config file with this:

<VirtualHost *:80>
   ServerName git.example.com

   DocumentRoot /usr/share/gitweb
   <Directory /usr/share/gitweb>
      Options ExecCGI
      DirectoryIndex gitweb.cgi

      AuthType Basic
      AuthName "Gitweb"
      AuthUserFile /home/git/htpasswd
      Require valid-user
   </Directory>
</VirtualHost>

Now, reload apache:

sudo service apache2 restart

and you should be able to login using your username and password you set up earlier by going to http://git.example.com.

Leave a Reply

Your email address will not be published. Required fields are marked *