I needed a container running an SVN server, and I knew that probably there are lots on the internet, so I started to search for it. I wasn’t satisfied of what I found: the requirement was to access the repository using both the WebDav protocol (i.e., http://) and the custom protocol (i.e., svn://), but all the images I was able to find offered just one of them. The conclusion is that I managed to create my own image.
In this tutorial I want to show you the process I followed to create such image. It could be not perfect, but maybe can be of help to someone… If you just need the image (it’s ok, we all are very busy! ;) ) you can pull it from the Docker Hub. Otherwise, you can find the Dockerfile and other configuration files in my GitHub repo.

Docker image

Let’s start building our Dockerfile. First of all, we need a proper base image to start with. The most lightweight Linux image we can use is Alpine Linux, a very basic system that provides just what is needed to start. Since we will need a process manager to automatically start our server, we can speed things up using the image provided by Scott Mebberson, which provides Alpine Linux together with S6 process management.

Then, we install the Apache2 web server (with other packages needed to access the SVN repository via http:// protocol) and, obviously, Subversion.

The next thing to setup is the parent folder of all our repositories. We can place it in /home/svn/ folder. We need also other two folders to properly run our services.

To access our repositories using the http:// protocol, we need an authentication file. We will use it later, for now we can just create it.

The Apache2 server should be configured for the access to the repositories via the WebDav protocol, so we need to create the following dav_svn.conf file.

This file should be put in the configuration folder of the server. So, we add the proper command in our Dockerfile.

The process manager should be instructed to start the Apache2 server and the SVN daemon when the container starts. We can create two run files, one for Apache2 and the other for Subversion (to be more specific, the svnserve process), that trigger the execution of our services.

The first run file, to start Apache2:

The second run file, to start Subversion:

We place these files in two different folders (the apache and subversion folders, respectively), and we add these folders in the services.d one of our image.

The last thing we need to do is to expose the proper ports.

The final result should be something like this.

Let’s place this Dockerfile inside a folder together with the other configuration files.

Ok, now we just need to open the terminal, navigate to the correct folder, and build our image.

Image configuration and test

Time to test our Docker image! :)

We should start our container in background, binding the correct ports to reach our services, and we can optionally attach a volume to the root of our repository (i.e., /home/svn/), just to have a local copy of our repositories (I mapped the folder /svn-root). It is good also to add a proper name to our container, like svn-server.

Let’s check if the container is running. We can do it using the docker ps command.

Ok, our container is running, but we need to configure username and password to access our repositories via http:// protocol. We can do it using the htpasswd command inside our container. I create a user with password user, just for test purposes.

We can check if everything is working properly simply by connecting to http://localhost/svn in our browser. We put our username and password when asked, and…

That’s good! We have an empty collection of repositories!

Now we need to test also the custom protocol. Open you terminal and try to connect to our container using svn. run the command svn info svn://localhost:3690.

Don’t worry about the error: there is not a repository yet, but we connected to the svn service inside our container.

Seems that everything is working fine!

Repository creation

We have our SVN server running in a container, now it’s time to create a repository!

Since we mapped the svn-root folder to the parent folder of the repositories in our container, we can create our repository there. Navigate to svn-root and run the command svnadmin create Test (I called it Test, you can call it the way you want). Inside svn-root you will find the folder of the new repository, which contains some default files.

Now we can try with the custom protocol, to see if we can obtain some info on our repository. Open the terminal, and try again with the svn info svn://localhost:3690/Test command.

Amazing! :)
Now we can checkout our repository using the http:// protocol. I prepared a folder (called svn-local) that will contain our local working copy. I will use a client called SmartSVN, but you can use the one you are more comfortable with.

Open you SVN client and choose to checkout an existing repository. When asked for the address, put http://127.0.0.1/svn/Test (I don’t know why, but SmarSVN seems to be unable to understand localhost).

The client will ask you username and password. Once authenticated, it will be ready to checkout our repository.

When asked for you local directory, put the path of the one you want to use to store the local working copy. In my case, the folder is svn-local.

Complete the process, and we are ready to work on our project! Let’s try to commit something. Go to you local working copy, and add a file named pippo.txt. Now open you client, and you should see the new created file.

Add it to you revision, and do a commit. Check that the file has been committed connecting to the repo using the browser (remember, the address is http://localhost/svn/Test).

We have our file in the repo, good!
Now, just to be complete in our test, let’s try to commit a file using the custom protocol. Before doing that, we need to configure the repository to grant write access to authenticated users. Go to the svn-root/Test/conf folder, and you will see some configuration files.

Let’s start adding the user to the passwd file. Simply put a line <username>=<password> in that file.

Then, we tell svnserve to use that file for the authentication of the users. We also set the writing permission to authenticated users. open the svnserve.conf file, and uncomment the following lines. Remember to remove the spaces between the words.

Once you did it, we can go to our working copy and create a new file topolino.txt. This time we use the custom protocol, so open the terminal, go to you local working copy (mine is svn-local/Test), and add the new file to the revision with the command svn add topolino.txt.
We are ready to commit: svn commit -m "Another commit test" --username user. Insert the password when requested.

Check that the new file is present.

That’s it! Everything is working as expected, we can now use our SVN server! :-)

TL;DR

Do you want a very lightweight (~30 MB) container image running an SVN server, that is accessible both via WebDav protocol (http://) and custom protocol (svn://)? Pull my Docker image: elleflorio/svn-server, or checkout my GitHub repo.

Enjoy! ;)

PhD, passionate about Distributed Systems. Functional Programming Enthusiast. Krav Maga black belt.