Step 1: Prepare your system

Install subversion, if not yet done:

root@testkraxn ~ # which svn
svn not found
root@testkraxn ~ # apt-get update
root@testkraxn ~ # apt-get install subversion
        The following NEW packages will be installed:
          libapr1 libaprutil1 libdb4.8 libneon27-gnutls libsvn1 subversion
        Do you want to continue [Y/n]? y

Create a single user and run the subversion server as that user. Be sure to make the repository in the filesystem owned by the subversion user as well. From a security point of view, this keeps the repo data well isolated and protected by filesystem permissions, changeable by only the Subversion server process itself.

root@testkraxn ~ # useradd -d /home/subversion -m subversion
root@testkraxn ~ # usermod -a -G subversion subversion
root@testkraxn ~ # chsh subversion # to whatever you prefer
root@testkraxn ~ # cd ~subversion
root@testkraxn ~ # mkdir ~subversion/svn-data
root@testkraxn ~ # chown subversion:subversion -R ~subversion/svn-data

Place a link in the filesystem so we can later access with svn://host:1111/svn/projectX

root@testkraxn ~ # ln -s /home/subversion/svn-data /svn

Step 2: Create a repository

root@testkraxn ~subversion # su subversion
subversion@testkraxn ~ % cd svn-data
subversion@testkraxn ~/svn-data % svnadmin create projectX

Edit your svnserve.conf like this:

subversion@testkraxn ~/svn-data % vim projectX/conf/svnserve.conf
subversion@testkraxn ~/svn-data % grep -vE '^\s*(#.*|)$' projectX/conf/svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz

[sasl]

Place your svn users here:

subversion@testkraxn ~/svn-data % vim projectX/conf/passwd
subversion@testkraxn ~/svn-data % grep -vE '^\s*(#.*|)$' projectX/conf/passwd
[users]
andre = asdf27

Step 3: Start and test the svn server daemon process

subversion@testkraxn ~/svn-data % svnserve -d
subversion@testkraxn ~/svn-data % sudo su
root@testkraxn ~ # nmap -sS localhost
PORT     STATE SERVICE
22/tcp   open  ssh
3690/tcp open  svn        <-- you should see this line

Now you should be able to checkout on localhost and from other hosts:

subversion@testkraxn ~/svn-data/projectX % cd /tmp
subversion@testkraxn /tmp % svn co svn://localhost/svn/projectX projectX
subversion@testkraxn /tmp % cd projectX
subversion@testkraxn /tmp/projectX % svn info
Repository Root: svn://localhost/svn/projectX
subversion@testkraxn /tmp/projectX % echo hello > test.txt
subversion@testkraxn /tmp/projectX % svn add test.txt
A         test.txt
subversion@testkraxn /tmp/projectX % svn ci -m "hello world test"
subversion@testkraxn /tmp/projectX % svn update
At revision 1.

or from another host:

anotheruser@anotherhost ~ % svn co svn://vbox0/svn/projectX projectX
A    projectX/test.txt
Checked out revision 1.

Step 4: Configure svn over ssh

This will improve security and convenience, since the users do not need a separate svn user and they can authenticate with a keyfile instead of typing and storing their passwords.

The following requirements must be given:

  • The authentication must use the systems unix user acconts. We do not want to manage a new user/password mapping for everybody.
  • In the configuration, we need to be able control the following:
    • Put users into groups and enable group based authentication rules.
    • Specify separate permissions for every directory.

Example:

On our system, we have two users:

    tester (the one that has readwrite access)
    leser (the one that cannot commit)

Both accounts are existing on the machine and are able to login via ssh.

Set file system permissions. Users not in group subversion are locked out:

root@testkraxn /etc/ssh # cd ~subversion
root@testkraxn ~subversion # ls -l
drwxrwxr-x 3 subversion subversion 4096 Dec  3 14:58 svn-data/
root@testkraxn ~subversion # chown subversion:subversion -R svn-data # to be sure :D
root@testkraxn ~subversion # chmod o-rwx -R svn-data
root@testkraxn ~subversion # ls -l
drwxrwx--- 3 subversion subversion 4096 Dec  3 14:58 svn-data/

Put users to group "subversion". This will allow to access the svn repository.

root@testkraxn /etc/ssh # usermod -G subversion tester
root@testkraxn /etc/ssh # groups tester
tester : tester subversion

Edit your authz file like this:

subversion@testkraxn ~/svn-data % cat projectX/conf/authz

[aliases]
[groups]
committergroup = tester
readgroup = leser, tester

[/] # relative to project root
# allow nothing by default:
* =
@readgroup = r
@committergroup = rw

[/tags]
* =
committergroup = rw

After this, you should be able to use the svn repo like this:

andrer@caracas ~ svn co svn+ssh://tester@vbox0/svn/projectX/trunk rw
Checked out revision 7.
Tutorial
another Reference

Optional: Setup websvn viewer for your server

DRAFT


******* install web svn (http://www.websvn.info) ********

root@virtubuntu ~ # apt-get install websvn

or
download bin from 
http://websvn.tigris.org/files/documents/1380/49057/websvn-2.3.3.zip

******* setup test repo ********

root@virtubuntu /var/lib # mkdir svn
root@virtubuntu /var/lib # cd svn
root@virtubuntu /var/lib/svn # svnadmin create helloworld
root@virtubuntu /var/lib/svn # ls -l
drwxr-xr-x 6 tester tester 4096 Sep 12 20:22 helloworld/

root@virtubuntu ~ # dpkg-reconfigure websvn

    Apache configuration:
    [*] apache2

    svn parent repositories:
    /var/lib/svn/helloworld

(apache runs as root in my case, so i do not bother.)

open a browser, and goto:
http://localhost/websvn/


Optional: Migrate SVN projects to avoid permission problems with websvn

DRAFT

If needed with this script you can migrate your projects to the fsfs file system type.

Note on permissions
Due to a limitation in the DB format, the 'svnlook' command needs read-write access to the repository (to create locks etc).
You need to give read-write permissions to the user running your webserver on all your repositories.

Another way of avoiding this problem is by creating SVN repositories with the --fs-type=fsfs option.
Existing DB repositories can be converted to the FSFS format by using the svnadmin dump/load commands.



******* setup in filesystem *********

I want to convert all projects that are in directory "public".
The target directory is "migration-stage"

andre@killerkraxn /data/subversion/svn-data/andre % ls -l
drwx------  5 andre andre 4096 2013-07-30 18:41 private/
drwxrwxr-x 36 andre andre 4096 2013-02-13 18:54 public/
andre@killerkraxn /data/subversion/svn-data/andre % ./migrate.sh public  # see below


******* migrate.sh script *********

#!/bin/bash

sourceRootDir="$1"                                                             
migratedRootDir="migration-stage"
mkdir -p "$migratedRootDir"

find "$sourceRootDir" -type d -mindepth 1 -maxdepth 1 \
| sort \
| while read sourceRepo
do
        migratedRepo="${migratedRootDir}${sourceRepo#$sourceRootDir}"
        dumpFile="$migratedRepo.dump"

        echo "migrating repository $sourceRepo to $migratedRepo ..."

        echo "1. create new repo with correct fs type: $migratedRepo"
        svnadmin create --fs-type=fsfs "$migratedRepo"

        echo "2. create svn dump to: $dumpFile"
        svnadmin dump "$sourceRepo" > "$dumpFile"

        echo "3. drop the dump in the new repo"
        cat "$dumpFile" | svnadmin load "$migratedRepo"

        echo "done with migration of $sourceRepo"; echo
done



******** example output *********

migrating repository public/web-jsf2-getstarted to migration-stage/web-jsf2-getstarted ...
1. create new repo: migration-stage/web-jsf2-getstarted

2. create svn dump to: migration-stage/web-jsf2-getstarted.dump
* Dumped revision 0.
* Dumped revision 1.

      [...]

* Dumped revision 11.
* Dumped revision 12.

3. drop the dump in the new repo
<<< Started new transaction, based on original revision 1
     * adding path : branches ... done.
     * adding path : tags ... done.
     * adding path : trunk ... done.
------- Committed revision 1 >>>
<<< Started new transaction, based on original revision 2
     * editing path : trunk ... done.
     * adding path : trunk/pom.xml ... done.
     * adding path : trunk/web ... done.
     * adding path : trunk/web/WEB-INF ... done.
     * adding path : trunk/web/WEB-INF/web.xml ... done.
------- Committed revision 2 >>>
<<< Started new transaction, based on original revision 3

      [...]

<<< Started new transaction, based on original revision 11
     * editing path : trunk/pom.xml ... done.
------- Committed revision 11 >>>
<<< Started new transaction, based on original revision 12
     * editing path : trunk/web/WEB-INF/web.xml ... done.
------- Committed revision 12 >>>
done with repo public/web-jsf2-getstarted