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
- Install PuTTY
- Install TortoiseSVN
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!