Setting up SVN and git shared hosting on Debian
This note explains how to setup a shared Git and a shared SVN repository on a Debian stable (jessie) server, incidentally a Raspberry Pi. Both repositories are served with Apache, using mod_dav_svn for SVN, and using the git-http-backend CGI for git. (Note that these aren't the only possible choices, but they are the ones I will present.)
The setup uses Apache Digest authentication (with
a file common to both SVN and git): the SVN and git setups are otherwise
independent. The setup uses SSL provided with Let's Encrypt, set up
with certbot
. For brevity I am omitting sudo
in all commands of this
tutorial.
Note that I am dumping this from memory after having done the setup, but I'm not guaranteeing that everything will work. If something does not work, please email me.
Set up the domain names
If your main domain is example.com
, then you probably want to set up
svn.example.com
and git.example.com
to point to the machine where you will
be hosting the repositories. This will allow you to configure each service
easily using virtual hosts, and makes it easier to move the hosting to a
different machine if you want.
You probably want to wait for the new DNS entries to have propagated before doing what follows, in particular for the Let's Encrypt challenge to work.
Install apache2 and certbot
apt-get install apache2 libapache2-svn libapache2-mod-svn
apt-get install certbot python-certbot-apache
Side note: certbot
is not yet available on jessie, you need to enable
jessie-backports. As my Raspberry
Pi uses Raspbian, this also means I had to set up
the Debian signing keys:
download the keys that apt-get update
complains about and install them
with apt-key add
.
Obviously you should also make sure that SVN and git are installed on the server.
Start your apache2 configuration
Add to the beginning of /etc/apache2/apache2.conf
the default hostname of your
machine (of course, change it to something reasonable):
ServerName machine.example.com
While you are at it, you can add the following to the bottom to avoid disclosing details of your Apache version:
ServerTokens Prod
ServerSignature Off
Now, create a file /etc/apache2/sites-available/000-git.conf
and add the
following, changing the domain name and email address (don't worry about the
DocumentRoot
, it doesn't matter):
<VirtualHost *:80>
ServerName git.example.com
ServerAdmin you@example.com
DocumentRoot /var/www/html/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Create /etc/apache2/sites-available/000-svn.conf
analogously (replacing git
by svn
). Then, enable the right sites with:
a2dissite 000-default
a2ensite 000-git
a2ensite 000-svn
Set up SSL with certbot
Run certbot --apache
: it should pick up the configuration files that you
created and understand what you are doing. Say that you want to enable encryption for both subdomains,
that you accept the license, and that you want the Secure setup where users are
redirected to the SSL version (we don't want the version control traffic ever to
happen in cleartext). Check that https://git.example.com/
and
https://svn.example.com/
both work with SSL, and that
http://
URLs redirect to the https://
variant.
Yes, it's just a 301 redirect, it's not
HSTS, but to me
this is good enough.
Create the user file
Authentication will be performed by Apache Digest, so create a password file with your own user using the following command (note that the second argument, the realm, is important because it is included in the digest):
htdigest -c /etc/vcs_passwd "example.com version control" yourlogin
Then, when you want to add more users, issue:
htdigest /etc/vcs_passwd "example.com version control" theirlogin
Ensure that the file is owned by www-data and only readable by them:
chown www-data:www-data /etc/vcs_passwd
chmod og-rwx /etc/vcs_passwd
Setting up Subversion
Now that the common SSL setup and user setup is done, let's start by setting up Subversion. For reference, the part of the SVN Book about what we are trying to do is here. I prefer creating one global repository and use path-based authorization to give access to relevant subsets to various users.
Creating the Subversion repository and setting up authorization
Create the repository, e.g.:
mkdir -p /var/svn
svnadmin create /var/svn/repos
We will be using path-based authorization. Create a file /var/svn/paths
with a
content like the following (check the path-based authorization
documentation
for details). Caution, it appears that path specifications (between square
brackets) do not work if you put a trailing slash, so do not put a trailing
slash, as in the following:
[/]
yourlogin = rw
close_friend = r
[/project]
close_friend = rw
other_friend = rw
Give ownership of everything to Apache with:
chown -R www-data:www-data /var/svn
Configuring Apache
First, you should enable the necessary modules:
a2enmod dav_svn authz_svn auth_digest
Next, restart Apache with service apache2 restart
.
Edit the file /etc/apache2/sites-enabled/000-svn-le-ssl.conf
which was created
by certbot, and add the following block in the VirtualHost
block:
<Location />
DAV svn
SVNPath /var/svn/repos
AuthType digest
AuthName "example.com version control"
AuthUserFile /etc/vcs_passwd
AuthzSVNAccessFile /var/svn/paths
Require valid-user
SSLRequireSSL
</Location>
Reload the Apache configuration with service apache2 reload
. Hopefully the
config should be accepted, and
you should be able to checkout on a remote machine:
svn co https://svn.example.com/ myrepos
You should then be able to commit, etc.
This guide does not cover the task of setting up a backup (e.g., a periodic
rsync) of the repository, i.e., the /var/svn
folder.
Setting up git
We will be using git-http-backend, and create multiple repositories with one user group per repository.
For now, create the structure:
mkdir -p /var/git/repos
touch /var/git/groups
You should then make sure that this is readable by www-data
.
Creating each git repository and setting up access rights
To create a git repository for project proj1
, do:
cd /var/git/repos
git init --bare proj1
chown -R www-data:www-data .
Now, add to the file /var/git/groups
a line to indicate who has the right to
access this project (this is both read and write access):
proj1: yourlogin close_friend other_friend
Configuring Apache (initial configuration)
This only needs to be done the first time.
First, you should enable the necessary modules:
a2enmod macro authz_groupfile cgi auth_digest
And restart Apache.
Next, edit the file
/etc/apache2/sites-enabled/000-git-le-ssl.conf
and add, inside the VirtualHost
block:
DocumentRoot /var/git/repos/
SetEnv GIT_PROJECT_ROOT /var/git/repos/
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias / /usr/lib/git-core/git-http-backend/
<Macro Project $repos>
<Location /$repos>
AuthType digest
AuthName "example.com version control"
AuthUserFile /etc/vcs_passwd
AuthGroupFile /var/git/groups
Require group $repos
SSLRequireSSL
</Location>
</Macro>
UndefMacro Project
Configuring Apache (for each project)
Now, each time you add a project, say proj1
, you should add the following line
just before the UndefMacro
line:
Use Project proj1
And of course you should issue service apache2 reload
. You should now be able
to do the following:
git clone https://git.example.com/proj1
To avoid getting asked about your password each time (and storing it in plaintext, which is OK if you trust the security of your machine and you use disk encryption), you can issue the following (see the end of this answer):
git config --global credential.helper store
As with Subversion, you should then arrange to back up the /var/git
folder.