In the afternoon I installed Subversion on my Dell Vostro running Lucid Lynx. Yesterday I had done a fresh install of Ubuntu Lucid Lynx 10.04.02 LTS and in order to be able to do some work I really had to restore the SVN repositories I keep my work in and make them accessible again.
Since I had been using the Apache web server to access SVN repositories via https on the previous installation of Ubuntu on my development computer without any issues I had decided to use this setup again.
From that ealier installation I recalled that just installing
the apache2
package as follows:
sudo apt-get install apache2
would install apache2-mpm-worker
and that if I
would install PHP later, in my case to be able to use
MediaWiki, it would be replaced by
apache2-mpm-prefork
. So in order to keep things
simple I installed the Apache web server version 2.2.14 by
installing PHP version 5.5.3.2 as follows:
sudo apt-get install php5
which installs apache2-mpm-prefork
.
If you like me get the following warning during the above installation of PHP:
apache2: Could not reliably determine the server's fully
qualified domain name, using 127.0.1.1 for ServerName
don't worry. Open /etc/apache2/httpd.conf
in,
for example vi
-- make sure to use
sudo
-- and add the following line to this
file, replacing ecce
with the hostname of your
computer:
ServerName ecce
I also enabled hostname look ups so I would get actual
hostnames instead of numerical IP addresses in the log files
Apache generates by adding the following line to
httpd.conf
as well:
HostnameLookups On
The next time you restart the Apache web server the "Could no reliably determine ..." warning should no longer be given.
Once the Apache web server has been installed it's time to
install Subversion, mod_dav_svn
; the module
that makes serving Subversion repositories through the
Apache HTTP server possible, and mod_authz_svn
;
the module that handles path-based authorization. The latter
two are in the same package, libapache2-svn
.
sudo apt-get install subversion
sudo apt-get install libapache2-svn
Don't restart Apache yet since SSL hasn't been configured and enabled yet.
I use a hierarchy of directories to organize the
repositories on my computer in /home/svn
which
I created by invoking sudo mkdir /home/svn
not
by adding a user svn
. I check out the
repositories under a directory Amber
in my home
directory following the same hierarchy. The name Amber is a
reference to Castle
Amber, the name I used up until a few years ago for my
company. Currently I am self-employed as a Perl programmer under my own name
which according to my bookkeeper is less of a hassle.
An excerpt of the hierarchy I currently use is given below:
.
`--admin
| `--invoices
| `--notes
| `--quotes
| `--seo-reports
| `--support
`--customers
| `--joe-customer-1
| | `--project-1
| | `--project-2
: :
`--in-house
| `--documents
: : :
| | `--ubuntu
| `--projects
| | `--ambercam
| | `--anti-spam
: : :
| | `--backup-tools
: : :
| | `--perl-modules
| | `--perl-snippets
: :
| `--sites
| | `--castleamber.com
| | `--johnbokma.com
: :
The complete tree I used to create the above excerpt was
generated using the following find
magic on the
command line:
find . -maxdepth 3 -name .svn -prune -o -type d -print \
| sort \
| sed -e 's,[^/]*/\([^/]*\)$,`--\1,' -e 's,[^/]*/,| ,g'
The -name .svn -prune
part skips descending
into .svn
directories. The -type d
limits the output to directories only and -maxdepth
3
limits the depth of the tree to 3 levels. The
sort
sorts the nodes and leaves of the tree and
the sed
command provides the tree
structure. Note that the colons in the output were manually
added by me to denote removed parts.
First, an SSL virtual host is needed so Subversion can
connect to this. Since I named my computer ecce
I created a file ssl-ecce
in the directory
/etc/apache2/sites-available
. The skeleton of
this file looks as follows:
<VirtualHost *:443>
ServerAdmin webmaster@ecce
# SSL related
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/apache.pem
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM
# See: /usr/share/doc/apache2.2-common/README.Debian.gz
SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# Enable Basic Authorization
<Directory />
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/ssl-ecce-svn.passwd
Require valid-user
SSLRequireSSL
</Directory>
# Add Location directives here
# Logging related
LogLevel warn
ErrorLog /var/log/apache2/ssl-ecce-error.log
CustomLog /var/log/apache2/ssl-ecce-access.log combined
CustomLog /var/log/apache2/ssl-ecce-svn-action.log \
"%h %u %t %{SVN-ACTION}e" env=SVN-ACTION
<VirtualHost>
Make sure you replace ecce
with the hostname of
your own computer (five times).
Note that this is a skeleton. You have to add a Location directive for each directory that can hold one or more repositories as will be explained below.
Also note that the last CustomLog directive; it logs Subversion actions to its own, more readable, log file.
Second, a self-signed SSL certificate has to be created. For this I issued the following two commands, the first creates the directory for storing the certificate and the second one generates the actual certificate:
sudo mkdir /etc/apache2/ssl
sudo /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf \
/etc/apache2/ssl/apache.pem
The latter asks for a host name. Enter the name of your
computer, in my case ecce
Third, since I use basic authorization, see the virtual host skeleton above, I had to create a file with my username and (a one-way hash of) my password, which I did as follows:
sudo htpasswd -c -m /etc/apache2/ssl-ecce-svn.passwd john
If you want to add more users, remember that the
-c
option is only required if the passwd file
doesn't exists yet. And again make sure to replace
ecce
in the filename with the host name of your
computer.
Finally, enable the SSL module, enable the newly created site, and restart the Apache web server as follows:
sudo a2enmod ssl
sudo a2ensite ssl-ecce
sudo /etc/init.d/apache2 restart
When you access the repository via svn
or a browser
you will get a warning about the self-signed certificate since
it's not issued by a trusted authority. Accept the certificate
permanently to stop this warning from showing up again.
An example of the output you can expect the first time you check out a repository follows below. Notice how, as expected, the password is asked for user 'john'.
svn co https://ecce/customers/fred/blue-widgets/trunk blue-widgets
Error validating server certificate for 'https://ecce:443':
- The certificate is not issued by a trusted authority. Use the
fingerprint to validate the certificate manually!
Certificate information:
- Hostname: ecce
- Valid: from Fri, 24 Jun 2011 19:28:19 GMT until Mon, 21 Jun 2021 19:28:19 GMT
- Issuer: ecce
- Fingerprint: **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**
(R)eject, accept (t)emporarily or accept (p)ermanently? p
Authentication realm: <https://ecce:443> Subversion Repository
Password for 'john':
Below follow four Subversion recipes to get you started.
Each time I get a new customer, for example Fred, I create a new directory to contain the repositories for each project of the customer as follows:
sudo mkdir /home/svn/customers/fred
Next, I add the following to ssl-ecce
:
<Location /customers/fred>
DAV svn
SVNParentPath /home/svn/customers/fred
</Location>
and reload the Apache web server as follows:
sudo /etc/init.d/apache2 reload
If a customer of mine, say Fred, has a project, say "Blue Widgets" I create a repository for this customer's project as follows:
sudo svnadmin create /home/svn/customers/fred/blue-widgets
sudo chown -R www-data: /home/svn/customers/fred/blue-widgets
followed by an initial import and check-out of the trunk:
cd ~/Amber/customers/fred
mkdir -p blue-widgets/{trunk,tags,branches}
svn import blue-widgets \
https://ecce/customers/fred/blue-widgets -m 'initial import'
rm -ri blue-widgets
svn co https://ecce/customers/fred/blue-widgets/trunk \
blue-widgets
I create a backup of a repository as follows. Again I use the fictitious customer Fred and his "Blue Widgets" projects as an example.
svnadmin -q dump /home/svn/customers/fred/blue-widgets \
| gzip -c9 customers-fred-blue-widgets.gz
The repository dump is compressed using gzip
.
The backup created in the previous section can be restored as follows:
sudo mkdir -p /home/svn/customers/fred/blue-widgets
sudo svnadmin create /home/svn/customers/fred/blue-widgets
gzip -cd customers-fred-blue-widgets.gz \
| sudo svnadmin load /home/svn/customers/fred/blue-widgets
sudo chown -R www-data: /home/svn/customers/fred/blue-widgets
Note that you have to add the Location directive to the ssl virtual host section as well if this hasn't been added yet, see "Adding a directory for new repositories".