How to use Subversion to manage a live site
(This tutorial relates specifically to my experiences with my host, MediaTemple, but the basics should be the same whoever you host with.)
Following a presentation by Juan Delgado at Refresh Cambridge last week, I resolved to update my workflow on freelance projects to include some sort of version control (VC). Juan made the point that running a live site as a checkout of a VC repository removes the need to FTP changes around; instead of trying to remember exactly which files you updated, you simply SSH into the live server and svn update the code to pick up any changes.
My ideal workflow therefore would be:
- Add a new project to a remote VC repository. (Why remote? It’s an added layer of protection in case my development machine dies, the house burns down, etc. I also backup, but still, can’t hurt.)
- Checkout the project to a working directory on my iMac at home.
- Checkout the project to the live server.
- Work on the project locally, check in changes and add files.
- Update the project on live.
Subversion and MediaTemple
I understand that some hosts provide a Subversion environment of some sort as standard. MediaTemple don’t, although they do have it installed on the (gs) GridServer package that I have. They also provide a useful page detailing how to create a Subversion repository—you only need to follow steps 1-3 to start with, though.
I had problems getting my SVN browser (Versions, although I also tried ZigVersion and Cornerstone) to connect to the new repository initially. Eventually I followed these instructions on creating public-private keys—and after that it worked perfectly.
The new workflow
So, now that I have a repository set up on my (mt) server, my workflow looks like this.
Create the project structure and import to SVN
SSH to the server using your admin email address:
ssh serveradmin%29example.com@s12345.gridserver.com
Create the project structure—I use a temporary folder for this:
example.com$ cd data/temp_projects
example.com/data/temp_projects$ mkdir mynewsite
example.com/data/temp_projects$ mkdir mynewsite/branches
example.com/data/temp_projects$ mkdir mynewsite/tags
example.com/data/temp_projects$ mkdir mynewsite/trunk
And finally import the new project into the repository:
example.com/data/temp_projects$ svn import mynewsite file:///home/12345/data/<repo>/mynewsite --message "Creating new project"
(Note that the 12345 bit is whatever your server number is with MediaTemple.)
Checkout the project to your working directory
Using your SVN browser of choice, connect to the repository (over svn+ssh as described in the articles above) and checkout the new project. You can now add and edit files, remembering to check them in when you’ve finished.
Checkout the project to the live site
On MediaTemple, all the sites on your server sit in a folder named ‘domains’, and each one (e.g. ‘example.com’) has a folder named ‘html’ inside it which is the web root.
SSH to the server again and navigate to the site folder:
ssh serveradmin%29example.com@s12345.gridserver.com
example.com$ cd domains/example.com
New you can checkout the project—but we don’t want a folder named ‘trunk’, so we rename the checkout folder to be ‘html’:
example:com/domains/example.com$ svn co file:///home/12345/data/<repo>/mynewsite/trunk html
Now in the future when you want to update the live site, rather than using FTP to copy updated files, you can SSH to the server, navigate to the site folder, and run:
svn update
Voila! Any changed or added files are transferred from the repository—no forgotten files or dropped connections.
Summary
As you are keeping the live site in sync with the development version, it is worth remembering that you should only check in files that do not break the trunk! If you’re in the middle of working on something and it’s currently not working, don’t check it in! Version control is not a backup solution.
Working this way also means that you can’t sneakily update a file on the live server to fix a bug; you have to fix on dev and then deploy to live. Which is how you should be working anyway. :)
Filed under: Technology.
Technorati tags: subversion svn version control mediatemple ssh
Bookmark this article with del.icio.us
Previously: Refresh Cambridge October: Subversion
Next: Dissentivisation
Comments
- Juan Delgado
- 46 days ago
Very nice :)
Just don’t forget to prevent people accessing your .svn folder that now is live on your server. If you are running under Apache a little bit of .htaccess magic will do:
RewriteRule ^(.*/)?\.svn/ – [F,L]
ErrorDocument 403 "Access ForbiddenI’m not an .htaccess master, so there might be better ways to achieve the same result.
Cheers!
Juan
- #2
- Gareth Rushgrove
- 46 days ago
Good to see you making the jump to using source control.
Agree with Brad, tagging releases is good practice, as is working outside trunk. You might be two weeks into a new features and a bug crops up on live. Also not checking code in that you don’t want to go live encourages you to not check in very often – which is bad practice, especially when you’re working with more than one person.
I’m also partial to automating everything, so capistrano or ant can prove useful to remove some of those key strokes. Plus you can hang code quality stuff of them too.
Next up; start automating database schema changes :)
- #3
- Matthew Pennell
- 45 days ago
@Bradley I haven’t really got my head around tags yet, but I agree it would be a better way to handle releases. For the majority of my work, though, it’s not an issue at the moment.
@Juan Good point, thanks.
@Gareth Automation would be good—I’ve never been able to follow your tutorials on the subject though. ;) CodeIgniter has a DBForge class that can be used to automate schema changes, so that’s on the list of things to build next.
- #4
I’d recommend not running your live site off trunk unless you’re very comfortable branching.
A workflow like this is better:
* Create your project;
* Check things into trunk until you’re ready to release;
* Create a tag (1.0, for example) in the tags directory;
* Release from the tag version only.
If multiple people are working on a project you may want to create branches for each feature.
Personally I release from trunk, but I work in a branch (I use Git so branches are a dime a dozen), and merge back to trunk when a feature is ready.