Setting Up Subversion W/ WebDav, Post-Commit Hook & Multiple Sites On Jaunty Jackalope (Ubuntu 9.04)

1 About this tutorial.

This tutorial was designed for someone setting up their 1st Jaunty Jackalope (Ubuntu 9.04) - Subversion server. When I first started with Subversion, I became very frustrated with the many tutorials that were vague on the key part of what I was installing... Subversion! I included some "ease of use" packages for us Linux newbs :).

Included in this tutorial:

  • Installing Webmin
  • WebDav Setup
  • How to prepare Jaunty Jackalope (Ubuntu 9.04) as a web/svn server
  • SSL Setup
  • How to create a SLL Certificate
  • How to setup a SVN SSL VHOST
  • How to setup a Staging VHOST
  • How to setup a Live VHOST
  • Subversion Setup
  • How to create a post-commit hook to auto-update your staging server

NOT in this tutorial:

  • How to setup Ubuntu (there are many tutorials for that)

Because I am fairly new to Linux, I like to work from my Windows box, see the following information for prerequisites for this tutorial...

Jaunty Jackalope (Ubuntu 9.04):

  • Install LAMP
  • Install SSH

Windows Box

If you have attempted to install SVN and failed, I suggest you blow out Ubuntu and install a fresh copy before proceeding! this tutorial needs to be followed to the "letter" to work. My install of Ubuntu is a standard server with LAMP and SSH only. If you have tried and failed, you may have different directory structures than I use in this tutorial

I used example.com in this tutorial, you will need to replace example with your .com and also have your stg. and svn. subdomains setup and pointing at your ip. Due to issues with my work VPN, I always have our users setup thier home networks as 192.168.2.0 In this tutorial I went with that IP

PROPs to Jeremy Speer for his many hours of Google Talk help! -Thanks dewd!

 

2 Setup Ubuntu's Network & Host.

sudo su

Edit /etc/network/interfaces.

sudo nano /etc/network/interfaces

so that it looks like this:...

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
        address 192.168.2.2
        netmask 255.255.255.0
        network 192.168.2.0
        broadcast 192.168.2.255
        gateway 192.168.2.1

Restart the network. (if you are in PuTTY you will need to reconnect)

sudo /etc/init.d/networking restart

Edit /etc/hosts to use your new IP.

sudo su
sudo nano /etc/hosts

Edit it to look like this...

127.0.0.1       localhost
192.168.2.2     EXP-01.example.com       EXP-01
# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Setup /etc/hostname to reflect your host.

echo EXP-01.example.com > /etc/hostname

Start it.

sudo /etc/init.d/hostname.sh start

When you run the following commands, both should reply EXP-01.example.com

hostname
hostname -f

 

3 Update Ubuntu & Install the needed packages.

Update and upgrade Ubuntu.

sudo apt-get update
sudo apt-get upgrade

Install the needed packages.

sudo apt-get install subversion libapache2-svn ssl-cert

Install webmin.

I like webmin to manage my servers from a https://www.example.com:10000, you can skip this if you want.

Edit /etc/apt/sources.list and add the following to the bottom...

sudo nano /etc/apt/sources.list
deb http://download.webmin.com/download/repository sarge contrib

Update again.

sudo apt-get update

Install Webmin.

sudo apt-get install webmin

 

4 Create your SSL cert and your Sites

When it propmts you, use svn.example.com as the host.

sudo mkdir /etc/apache2/ssl
sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem

Enable SSL

sudo a2enmod ssl
/etc/init.d/apache2 restart

I feel more secure not leaving the default sites, so I disble them here.

sudo a2dissite default
sudo a2dissite default-ssl

We will now create the VHOSTs for all three of this tutorial's sites.

#START# SSL SVN site

sudo nano /etc/apache2/sites-available/svn.example.com

Copy paste the following in the new file.

<virtualhost *:443>
ServerName svn.example.com
ServerAdmin webmaster@localhost
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem
<DirectoryMatch "^/.*/.svn/*">
    Order deny,allow
    Deny from all
</DirectoryMatch>
ErrorLog /var/log/apache2/ssl-error.log
CustomLog /var/log/apache2/ssl-access.log combined
ServerSignature On
</virtualhost>

Enable the SVN Site

sudo a2ensite svn.example.com

#END# SSL SVN site.

#START# Staging site

sudo nano /etc/apache2/sites-available/stg.example.com

Copy paste the following in the new file.

<VirtualHost *:80>
        ServerName stg.example.com
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/stg/example.com/httpdocs/
	<Directory />
		Options FollowSymLinks
		AllowOverride All
	</Directory>
	<Directory /var/www/stg/example.com/httpdocs/>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride All
		Order allow,deny
		allow from all
	</Directory>
	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	</Directory>
	ErrorLog /var/log/apache2/error.log
	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn
	CustomLog /var/log/apache2/stg-example-access.log combined
    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
</VirtualHost>

Enable the Staging Site

sudo a2ensite stg.example.com

#END# Staging site.

#START# Live site

sudo nano /etc/apache2/sites-available/live.example.com

Copy paste the following in the new file.

<VirtualHost *:80>
        ServerName www.example.com
        ServerAlias example.com
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/live/example.com/httpdocs/
	<Directory />
		Options FollowSymLinks
		AllowOverride All
	</Directory>
	<Directory /var/www/live/example.com/httpdocs/>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride All
		Order allow,deny
		allow from all
	</Directory>
	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	</Directory>
	ErrorLog /var/log/apache2/error.log
	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn
	CustomLog /var/log/apache2/live-example-access.log combined
    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
</VirtualHost>

Enable the Live Site

sudo a2ensite live.example.com

#END# Live site.

Make the document folders for your sites

sudo mkdir /var/www/stg
sudo mkdir /var/www/live

 

5 Setup Subversion w/WebDAV

Backup the existing DAV config

sudo mv /etc/apache2/mods-available/dav_svn.conf /etc/apache2/mods-available/dav_svn.bak

Create a new DAV config:

sudo nano /etc/apache2/mods-available/dav_svn.conf

Copy paste the following in the new file.

<Location /svn>
DAV svn
SVNParentPath /var/lib/svn
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/dav_svn.passwd
Require valid-user
<LimitExcept GET PROPFIND OPTIONS REPORT>
</LimitExcept>
SSLRequireSSL
</Location>

Create your first SVN user.

sudo htpasswd -cm /etc/apache2/dav_svn.passwd usera

New Password

Re-Type new Password

To create more users, drop the -cm.

sudo htpasswd /etc/apache2/dav_svn.passwd userb

New Password

Re-Type new Password

Create the SVN repository root.

sudo mkdir /var/lib/svn

Creat your first repository.

sudo svnadmin create /var/lib/svn/example.com

Create a repository structure

sudo svn mkdir file:///var/lib/svn/example.com/trunk file:///var/lib/svn/example.com/tags file:///var/lib/svn/example.com/branches -m "example.com Initial SVN Structure"

Committed revision 1.

Checkout the repository to you staging folder.

sudo svn co file:///var/lib/svn/example.com/trunk /var/www/stg/example.com

Checked out revision 1.

The following is only to create the /var/www/stg/example.com/httpdocs so that apache doest "bark" at us when we restart it.

Add the Staging www-root folder.

sudo mkdir /var/www/stg/example.com/httpdocs

Add the new folder to versioning.

cd /var/www/stg/example.com/
sudo svn add httpdocs/

Ahttpdocs

Commit the changes to the repository.

sudo svn commit httpdocs/ -m "Adding intial Staging root folder -usera"

Adding httpdocs

Committed revision 2.

Checkout the repository to your live folder.

sudo svn co file:///var/lib/svn/example.com/trunk /var/www/live/example.com

Because you commited the staging changes to the repo, when you check out the repo to the live folder, the httpdocs/ is already there!

ls /var/www/live/example.com/

This is important, make sure www-data owns all of it. This will allow post-commits to work remotely.

sudo chown -R www-data:www-data /var/lib/svn/
sudo chown -R www-data:www-data /var/www/

Reload Apache2.

sudo /etc/init.d/apache2 reload

The following sites now work!

https://svn.example.com/svn/example.com/ (this one requires you to login with the webdav user and pass you created)

http://stg.example.com/

http://www.example.com/

WARNING the following should only be done if your server is not open to the public, I did this to save logging into the server every time to update my staging copy, which is behind a firewall... our actual servers are on a completely different machine. There are other ways to get post-commits to work.

6 Creating the post-commit Hook

A post commit hook will let SVN automatically update the httpdocs/ on your staging server, this is very handy when you are using ToirtoiseSVN from a local dev box. It prevents you from having to log into the SVN server to update your staging working copy.

Add www-data as a sudoer.

sudo nano /etc/sudoers

Copy paste the following at the end of the file.

www-data ALL=(ALL) NOPASSWD:ALL

Create the post-commit file

sudo cp /var/lib/svn/example.com/hooks/post-commit.tmpl /var/lib/svn/example.com/hooks/post-commit

Make the post-commit file executable.

sudo chmod +x /var/lib/svn/example.com/hooks/post-commit

Edit the post-commit file.

sudo nano /var/lib/svn/example.com/hooks/post-commit

Alter the file to look like this.

#!/bin/sh
# POST-COMMIT HOOK
#
# The post-commit hook is invoked after a commit.  Subversion runs
# this hook by invoking a program (script, executable, binary, etc.)
# named 'post-commit' (for which this file is a template) with the
# following ordered arguments:
#
#   [1] REPOS-PATH   (the path to this repository)
#   [2] REV          (the number of the revision just committed)
#
# The default working directory for the invocation is undefined, so
# the program should set one explicitly if it cares.
#
# Because the commit has already completed and cannot be undone,
# the exit code of the hook program is ignored.  The hook program
# can use the 'svnlook' utility to help it examine the
# newly-committed tree.
#
# On a Unix system, the normal procedure is to have 'post-commit'
# invoke other programs to do the real work, though it may do the
# work itself too.
#
# Note that 'post-commit' must be executable by the user(s) who will
# invoke it (typically the user httpd runs as), and that user must
# have filesystem-level permission to access the repository.
#
# On a Windows system, you should name the hook program
# 'post-commit.bat' or 'post-commit.exe',
# but the basic idea is the same.
#
# The hook program typically does not inherit the environment of
# its parent process.  For example, a common problem is for the
# PATH environment variable to not be set to its usual value, so
# that subprograms fail to launch unless invoked via absolute path.
# If you're having unexpected problems with a hook program, the
# culprit may be unusual (or missing) environment variables.
#
# Here is an example hook script, for a Unix /bin/sh interpreter.
# For more examples and pre-written hooks, see those in
# the Subversion repository at
# http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
# http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/

REPOS="$1"
REV="$2"

#/usr/share/subversion/hook-scripts/commit-email.pl \
#  "$REPOS" "$REV" [email protected]
sudo svn update /var/www/stg/example.com >> /var/lib/svn/logs/exampleup.log

Create a SVN log directory.

sudo mkdir /var/lib/svn/logs

Create the log file for update tracking.

sudo touch /var/lib/svn/logs/exampleup.log

Give www-data ownership.

sudo chown -R www-data:www-data /var/lib/svn/logs/exampleup.log

Now when you commit a file from ToroiseSVN on your local machine, you dont have to svn up on the staging server, the commit does it for you.

To update your live site, you still have to login to the server and run the update on the live folders. I do this so I dont accidently screw up my live server,

sudo svn up /var/www/live/example.com

 

That's it!

I hope this tutorial helps save all of you some frustration!

Share this page:

7 Comment(s)