Since gitorious' shutdown I decided it was time to start hosting my
own git repositories for my own little projects (although the company
which took over gitorious has a Free software offering it seems that
their hosted offering is based on the proprietary version, and in any
case
once bitten, twice shy and all that).
After a bit of investigation I settled on using
gitolite and
gitweb. I did consider
(and even had a vague preference for)
cgit but it wasn't available in Wheezy
(even backports, and the backport looked tricky) and I haven't
upgraded my VPS yet. I may reconsider cgit this once I switch to
Jessie.
The only wrinkle was that my VPS is shared with a friend and I didn't
want to completely take over the
gitolite
and
gitweb
namespaces in
case he ever wanted to setup
git.hisdomain.com
, so I needed
something which was at least somewhat compatible with
vhosting.
gitolite
doesn't appear to support such things out of the
box but I found an
interesting/useful
post
from Julius Plenz which included sufficient inspiration that I thought
I knew what to do.
After a bit of trial and error here is what I ended up with:
Install gitolite
The
gitolite website has
plenty of documentation on configuring gitolite. But since
gitolite
is
in Debian its even more trivial than even the quick install makes out.
I decided to use the newer
gitolite3 package from
wheezy-backports
instead of the
gitolite (v2) package
from Wheezy. I already had backports enabled so this was just:
# apt-get install gitolite3/wheezy-backports
I accepted the defaults and gave it the public half of the ssh key
which I had created to be used as the
gitolite
admin key.
By default this added a user
gitolite3
with a home directory of
/var/lib/gitolite3
. Since they username forms part of the URL used
to access the repositories I want it to include the 3, so I edited
/etc/passwd
,
/etc/groups
,
/etc/shadow
and
/etc/gshadow
to say
just
gitolite
but leaving the home directory as
gitolite3
.
Now I could clone the
gitolite-admin
repo and begin to configure
things.
Add my user
This was simple as dropping the public half into the
gitolite-admin
repo as
keydir/ijc.pub
, then
git
add
,
commit
and
push
.
Setup vhosting
Between
the gitolite
docs and
Julius'
blog
post
I had a pretty good idea what I wanted to do here.
I wasn't too worried about making the vhost transparent from the
developer's (ssh:// URL) point of view, just from the
gitweb
and
git clone
side. So I decided to adapt things to use a simple
$VHOST/$REPO.git
schema.
I created
/var/lib/gitolite3/local/lib/Gitolite/Triggers/VHost.pm
containing:
package Gitolite::Triggers::VHost;
use strict;
use warnings;
use File::Slurp qw(read_file write_file);
sub post_compile
my %vhost = ();
my @projlist = read_file("$ENV HOME /projects.list");
for my $proj (sort @projlist)
$proj =~ m,^([^/\.]*\.[^/]*)/(.*)$, or next;
my ($host, $repo) = ($1,$2);
$vhost $host //= [];
push @ $vhost $host => $repo;
for my $v (keys %vhost)
write_file("$ENV HOME /projects.$v.list",
atomic => 1 , join("\n",@ $vhost $v ));
1;
I then edited
/var/lib/gitolite3/.gitolite.rc
and ensured it
contained:
LOCAL_CODE => "$ENV HOME /local",
POST_COMPILE => [ 'VHost::post_compile', ],
(The first I had to uncomment, the second to add).
All this trigger does is take the global
projects.list
, in which
gitolite
will list any repo which is configured to be accessible via
gitweb
, and split it into several vhost specific lists.
Create first repository
Now that the basics were in place I could create my first repository
(for hosting
qcontrol).
In the
gitolite-admin
repository I edited
conf/gitolite.conf
and added:
repo hellion.org.uk/qcontrol
RW+ = ijc
After adding, committing and pushing I now have
"/var/lib/gitolite3/projects.list" containing:
hellion.org.uk/qcontrol.git
testing.git
(the
testing.git
repository is configured by default) and
/var/lib/gitolite3/projects.hellion.org.uk.list
containing just:
qcontrol.git
For cloning the URL is:
gitolite@$ VPSNAME :hellion.org.uk/qcontrol.git
which is rather verbose (
$ VPSNAME
is quote long in my case too),
so to simplify things I added to my
.ssh/config
:
Host gitolite
Hostname $ VPSNAME
User gitolite
IdentityFile ~/.ssh/id_rsa_gitolite
so I can instead use:
gitolite:hellion.org.uk/qcontrol.git
which is a bit less of a mouthful and almost readable.
Configure gitweb (http:// URL browsing)
Following the
documentation's
advice I edited
/var/lib/gitolite3/.gitolite.rc
to set:
UMASK => 0027,
and then:
$ chmod -R g+rX /var/lib/gitolite3/repositories/*
Which arranges that members of the
gitolite
group can read anything
under
/var/lib/gitolite3/repositories/*
.
Then:
# adduser www-data gitolite
This adds the user
www-data
to the
gitolite
group so it can take
advantage of those relaxed permissions. I'm not super happy about this
but since gitweb runs as
www-data:www-data
this seems to be the
recommended way of doing things. I'm consoling myself with the fact
that I don't plan on hosting anything sensitive... I also arranged
things such that members of the groups can only list the contents of
directories from the vhost directory down by setting
g=x
not
g=rx
on higher level directories. Potentially sensitive files do not have group
permissions at all either.
Next I created
/etc/apache2/gitolite-gitweb.conf
:
die unless $ENV GIT_PROJECT_ROOT ;
$ENV GIT_PROJECT_ROOT =~ m,^.*/([^/]+)$,;
our $gitolite_vhost = $1;
our $projectroot = $ENV GIT_PROJECT_ROOT ;
our $projects_list = "/var/lib/gitolite3/projects.$ gitolite_vhost .list";
our @git_base_url_list = ("http://git.$ gitolite_vhost ");
This extracts the vhost name from
$ GIT_PROJECT_ROOT
(it must be
the last element) and uses it to select the appropriate vhost specific
projects.list
.
Then I added a new vhost to my apache2 configuration:
<VirtualHost 212.110.190.137:80 [2001:41c8:1:628a::89]:80>
ServerName git.hellion.org.uk
SetEnv GIT_PROJECT_ROOT /var/lib/gitolite3/repositories/hellion.org.uk
SetEnv GITWEB_CONFIG /etc/apache2/gitolite-gitweb.conf
Alias /static /usr/share/gitweb/static
ScriptAlias / /usr/share/gitweb/gitweb.cgi/
</VirtualHost>
This configures
git.hellion.org.uk
(don't forget to update DNS too)
and sets the appropriate environment variables to find the custom
gitolite-gitweb.conf
and the project root.
Next I edited
/var/lib/gitolite3/.gitolite.rc
again to set:
GIT_CONFIG_KEYS => 'gitweb\.(owner description category)',
Now I can edit the repo configuration to be:
repo hellion.org.uk/qcontrol
owner = Ian Campbell
desc = qcontrol
RW+ = ijc
R = gitweb
That
R
permission for the
gitweb
pseudo-user causes the repo to be
listed in the global
projects.list
and the trigger which we've added
causes it to be listed in
projects.hellion.org.uk.list
, which is
where our custom
gitolite-gitweb.conf
will look.
Setting
GIT_CONFIG_KEYS
allows those options (
owner
and
desc
are
syntactic sugar for two of them) to be set here and propagated to the
actual repo.
Configure git-http-backend (http:// URL cloning)
After all that this was pretty simple. I just added this to my vhost
before the
ScriptAlias / /usr/share/gitweb/gitweb.cgi/
line:
ScriptAliasMatch \
"(?x)^/(.*/(HEAD \
info/refs \
objects/(info/[^/]+ \
[0-9a-f] 2 /[0-9a-f] 38 \
pack/pack-[0-9a-f] 40 \.(pack idx)) \
git-(upload receive)-pack))$" \
/usr/lib/git-core/git-http-backend/$1
This (which I stole straight from the
git-http-backend(1)
manpage
causes anything which
git-http-backend
should deal with to be sent
there and everything else to be sent to
gitweb
.
Having done that access is enabled by editing the repo configuration
one last time to be:
repo hellion.org.uk/qcontrol
owner = Ian Campbell
desc = qcontrol
RW+ = ijc
R = gitweb daemon
Adding
R
permissions for
daemon
causes
gitolite
to drop a stamp
file in the repository which tells
git-http-backend
that it should
export it.
Configure git daemon (git:// URL cloning)
I actually didn't bother with this,
git http-backend
supports the
smart HTTP mode which
should be as efficient as the git
protocol. Given
that I couldn't see any reason to run another network facing daemon on
my VPS.
FWIW it looks like vhosting could have been achieved by using the
--interpolated-path
option.
Conclusion
There's quite a few moving parts, but they all seems to fit together
quite nicely. In the end apart from adding
www-data
to the
gitolite
group I'm pretty happy with how things ended up.