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 theSVN_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
2 comments