Posted by tobi — 03:47 PM Feb 14
How do I deploy my code on a production server?
A few months back we had this little discussion in IRC to which david replied that he keeps different versions of his production apps on their respective directories and uses a symlink to hook up a working copy to the web server.
The big advantage in this is that you can test the code before restarting the web server since the current web site runs untouched. This has saved me from deploying quite a couple of bugs in the beginning and it prompted me to install damagecontrol.
Over the last couple of weeks I have tried to automate this process. What I came up with is a script which basically acts as a batch handler for server deployment.
Take for instance Hieraki. Issuing deploy hieraki runs through the following steps:
- ssh connect to production server
- checkout the latest version from subversion
- run all unit tests using rake
- set permissions on log dir
- point the hieraki/latest symlink to the newly deployed copy
- restart apache gracefully
The current version of my deploy script reads the file ~/.deployrc for its configuration. In hieraki’s case this looks like this:
hieraki:
server: myserver
checkout: svn export svn://myserver/hieraki/trunk
directory: /var/www/applications/hieraki
test: RAILS_ENV=production rake
after_test:
- chmod 777 log/
- chmod 666 log/*
after_commit:
- sudo /etc/init.d/apache reload
A nice and clean yaml config file as you can see. Hope this is a useful starting point for others.
Download the script here

Ben Jackson 01 Aug 17:03
Fantastic! I love this. A couple of comments:
- I put the base config file in /etc/.deployrc and symlinked it from all of my home directories.
- I put a copy in /usr/local/bin and changed it to grab the config from /etc/.deployrc and take a username and password from the config. Now I can run the script as a subversion post-commit hook under my apache user.
- I had to modify the “commit” def to remove the symlink before creating a new one as I was getting “Operation not permitted” errors on the server:
do_exec “rm #{$config[‘target’]}”