Automatic Post-commit Checkout

Subversion can be a very useful tool for developing Web sites or Web-based applications. You may wonder, though, how that would work. After you commit your changes to your repository, how do you have them reflected on your site? The easiest method is to have your site’s directory on the server be a working copy checked out from your Subversion repository. If you elect to do this be certain to modify your site’s .htaccess to prevent users from browsing Subversion’s control files. Something simple in the root of your site such as the following will suffice.

RedirectMatch 403 /\.svn.*$

Additionally you can configure your site to automatically check out the current sources from your repository by using Subversion’s “hook scripts“. In short, the script called hooks/post-commit will be executed by the web server each time new sources are checked into your repository. Be advised that when the web server executes this script it is running in the security context of the dhapache user — this user does not and should not (for security reasons) have the necessary permissions to modify the files in your web site’s directory. As such we need to arrange for the post-commit script to run the update in the security context of a user with the privileges necessary to update your site.

Users familiar with UNIX systems will recognize that this is a task for a setuid binary. Unfortunately the DreamHost /home/ directories are NFS filesystems which are, for security reasons, mounted with setuid disabled. Fortunately the workaround is trivial — simply set up your update script as a CGI script and have the Subversion post-commit hook invoke this script. Instructions follow.

1. Create a private directory on your website to host your updater script such as /home/username/mysite.com/cgi-bin/pri

1b. And set its permissions so that only the user has write access to it.

chmod 755 pri

2. Secure the private directory by creating a .htaccess file with contents similar to the following.

AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/username/mysite.com/cgi-bin/pri/.htpasswd
Require valid-user

3. Using the htpasswd utility create the .htpasswd file by running the following command in your /home/username/mysite.com/cgi-bin/pri directory. For security reasons make up a new username and password and do not re-use the username and password of a user you have created on your server or a user you have given access to your subversion repository.

htpasswd -bc .htpasswd someuser somepasswd

4. Now that you have created and secured a directory for this special CGI script to live in, create a script in that directory called do_update.cgi with the following contents.

#!/bin/sh
set -f
echo "Content-type: text/plain; charset=iso-8859-1"
echo
/usr/bin/svn update /home/username/mysite.com

4b. Don’t forget to give execution privilege to your file. Only the user can have write access to it.

chmod 755 do_update.cgi

5. Finally, modify your /home/username/svn/projectname/hooks/post-commit to invoke your CGI script so your site will update after each commit.

#!/bin/bash
wget --http-user=someuser --http-passwd=somepasswd -O - http://mysite.com/cgi-bin/pri/do_update.cgi

5b. Don’t forget to give execution privilege to your file. Again, only the user can have write access to it.

chmod 755 post-commit