Setting up Subversion

Subversion is a versatile version control system. This article looks at how to set up subversion on Amazon’s Linux (RHEL/CentOS derived), and the necessary setup for using it with Apache (proxied through Nginx), as well as the setup of a repository, and the use of hooks to automatically update a live (non-production) working copy.

Basic Setup

Install subversion and the SVN DAV module for apache, from the amzn repository (currently v. 1.6.15-1.8):

yum install subversion mod_dav_svn

Create a directory to store all your repositories:

mkdir /var/www/html/svn_repos/

Notes:

  • You can use the -p switch to create necessary subdirectories
  • Do NOT use the path above if /var/www/html can be accessed through your web-server server)

Note: if installed using a package manager, the subversion binaries should be in your $PATH, if not, run whereis to locate them, and prefix the commands below with the correct path. Typically, this is either /usr/bin (from yum) or /usr/local/subversion/bin/ (from source).

Create a Repository

To create the initial repository run:

svnadmin create /var/www/html/svn_repos/REPOSITORY_NAME

This will create the folder above, as well as the necessary sub-folders/files within it.

As mentioned above, my specific setup uses Nginx as a front-end server proxying to Apache on the backend. Since Nginx’s support for DAV is limited, and presently insufficient for subversion, it is necessary to proxy to a backend server – in this case apache.

Repository over HTTP

I want to run my repository from a subdomain svn.domain.com. Therefore, I need to setup the subdomain under both nginx and apache.

Nginx

/etc/nginx/sites-enabled/mydomain.com.conf

server {
     server_name svn.mydomain.com;
     location / {
          access_log off;
          proxy_pass   http://127.0.0.1:8080;
     }
}

Apache

Since we installed via yum, the needed apache module(s) should already be added to your apache configuration, in /etc/httpd/conf.d/subversion.conf.

/etc/httpd/conf.d/mydomain.com.conf:

<VirtualHost 127.0.0.1:8080>
     ServerName svn.mydomain.com
     ErrorLog /var/log/virtualmin/svn.mydomain.com_error_log
     CustomLog /var/log/virtualmin/svn.mydomain.com_access_log combined
     <Location />
          DAV svn
          SVNPath /var/www/html/svn_repos/REPOSITORY_NAME
          AuthType Basic
          #Realm/Title of login dialog
          AuthName "myDomain SVN Repository"
          #Full path to auth file created with htpasswd
          AuthUserFile /var/www/html/svn_repos/REPOSITORY_NAME/conf/svn-auth
          Require valid-user
     </Location>
</VirtualHost>

Notes:

  • Ideally, you should run your subversion subdomain over SSL.
  • You can use the Location block above to have the repository served on a sub-folder of the site.

We now need to create the AuthUserFile we specified above:

htpasswd -cmd /var/www/html/svn_repos/REPOSITORY_NAME/conf/svn-auth USER_NAME

Note: the -c switch creates a new file – it should only be used for the FIRST user, omit the -c switch for all subsequent users.

Reload apache and nginx and you should be able to navigate to your new subdomain in a browser. You should be at revision 0.

service httpd reload
service nginx reload

 

Repository Layout

We will now create the basic layout of our repository, and add the initial files.

A typical layout has the following folders:

  • trunk (the main branch)
  • branches (side projects/major additions/releases)
  • tags (point in time snapshots)

Note: subversion does not actually distinguish between branches and tags

We will create these three directories, and copy our existing project to trunk. The folder will be temporary, so we will create them in /tmp

mkdir -p /tmp/svn/{branches,tags}

If you are using a project already on the server, you can copy it:

cp -R /var/www/html/mydomain.com/public_html /tmp/svn/trunk

Otherwise:

  • Create the ‘trunk’ directory (mkdir /tmp/svn/trunk)
  • Upload a copy of your project (e.g. zipped/tar-gzipped) (via scp/sftp ideally)
  • Extract the files into the trunk

We will now import the layout and files into our new repository:

svn import /tmp/svn/ file:///var/www/html/svn_repos/REPOSITORY_NAME -m "Initial import"

Notes:

  • If you leave out the -m (or a -F) switch, and have not set the SVN_EDITOR environment variable, you will get an error.
  • You can use the URL to the repository http://svn.mydomain.com/ instead of the file path.

Delete the temporary files created:

rm -rf /tmp/svn/

At this point, our repository is setup.

Live copy of the repository head

As mentioned above, in this setup, we are creating a subdomain for the subversion repository. Firstly, we should create the necessary folders, etc – this may be done with Virtualmin, cPanel, etc., or can be done manually). I am using a subdomain created after the format used by Virtualmin.

cd /var/www/html/mydomain.com/domains/test.mydomain.com/
svn checkout file:///var/www/html/svn_repos/REPOSITORY_NAME/trunk public_html

Note: the file path (with the trunk directory does not actually exist – but the svn import command will look at the repository not the physical files)

Alternatively, you can use the URL to checkout:

svn checkout http://svn.mydomain.com/trunk/ public_html

Create the subdomain on nginx:

/etc/nginx/sites-enabled/mydomain.com.conf:

server {
     server_name  test.mydomain.com;
     access_log  /var/www/html/mydomain.com/domains/test.mydomain.com/logs/nginx_access.log;
     error_log  /var/www/html/mydomain.com/domains/test.mydomain.com/logs/nginx_error.log;
     root   /var/www/html/mydomain.com/domains/test.mydomain.com/public_html/;
     include /etc/nginx/sites-enabled/default.inc;
}

Note: You can view the basis of my default.inc file in my article Setting up nginx as a Reverse Proxy

Create the subdomain on apache (my base setup uses Webmin/Virtualmin, so this block modified from that).

/etc/httpd/conf.d/mydomain.com.conf:

<VirtualHost 127.0.0.1:8080>
     ServerName test.mydomain.com
     DocumentRoot /var/www/html/mydomain.com/domains/test.mydomain.com/public_html
     ErrorLog /var/log/virtualmin/mydomain.com_error_log
     CustomLog /var/log/virtualmin/mydomain.com_access_log combined
     ScriptAlias /cgi-bin/ /var/www/html/mydomain.com/cgi-bin/
     DirectoryIndex index.html index.htm index.php index.php4 index.php5
     <Directory /var/www/html/mydomain.com/domains/test.mydomain.com/public_html>
          Options -Indexes +IncludesNOEXEC +FollowSymLinks
          allow from all
          AllowOverride All
     </Directory>
     <Directory /var/www/html/mydomain.com/cgi-bin>
          allow from all
     </Directory>
</VirtualHost>

 

Auto-updating the working copy

Finally, we want any commits to the repository to automatically update the live test site:

To do this, we use a ‘hook’. The hook scripts (located in /var/www/html/svn_repos/REPOSITORY_NAME/hooks) are executed following specific actions. In this case, we want to run svn update after (post) a commit (so the post-commit hook):

Create a logs directory:

mkdir /var/www/html/svn_repos/REPOSITORY_NAME/logs/

Create an empty log file:

touch /var/www/html/svn_repos/REPOSITORY_NAME/logs/post-commit.log

Create a new file (post-commit) (or copy the template provided (post-commit.tmpl))

vi /var/www/html/svn_repos/REPOSITORY_NAME/hooks/post-commit

Add the command for svn update to the hook script (and send the output to a log file):

#!/bin/sh

#The following 2 lines are not used in this script, but may be used for more complex scripts
REPOS="$1"
REV="$2"

/usr/bin/svn update /var/www/html/mydomain.com/domains/test.mydomain.com/public_html/ >> /var/www/html/svn_repos/REPOSITORY_NAME/logs/post-commit.log

Make the hook executable:

chmod +x /var/www/html/svn_repos/REPOSITORY_NAME/hooks/post-commit

Note: suexec does not work with mod_dav_svn (or anything other than CGI)

Set the correct ownership on your test subdomain:

chown -R USER:GROUP /var/www/html/mydomain.com/domains/test.mydomain.com/

Set the correct ownership on your repository (should matching the ownership of your subdomain) :

chown -R USER:GROUP /var/www/html/svn_repos/REPOSITORY_NAME/

Reload Nginx and Apache:

service nginx reload
service httpd reload

 

Final Points

  • If you wish to use svn from within PHP – e.g. for versioning user submitted files, etc. – there is a pecl extension (svn) available
  • A handy client-side tool for working with subversion repositories is Tortoise-SVN, although, other software (e.g. Dreamweaver) may have built-in support for subversion.

References

Version Control with Subversion: http://svnbook.red-bean.com/nightly/en/index.html

By cyberx86

Just a random guy who dabbles with assorted technologies yet works in a completely unrelated field.

2 comments

Leave a comment

Your email address will not be published. Required fields are marked *