This month's talk by the PHPEM group was about different deployment methods for web applications, specifically Capistrano. This month the lecture was once again given by Tom Graham (@noginn) of Jadu due to the original speaker having to back out at the last minute.
The basic idea of the talk is that the method of deployment over (S)FTP can be tiresome and is not always the best method of deploying new releases of your web application. You can run into problems here with knowing what version from your repository is rolled out and when you do roll out it's not always easy to know what dependencies there are. This can lead to catastrophic problems when updating live systems and could easily incur more downtime than actually required.
One possible solution is to use Capistrano which was developed by Jamis Buck for 37signals as a way of deploying Ruby on Rails. The prerequisite for using this though is that the target server has the ability to accept connections over SSH and that the development environment you run this from must have Ruby and RubyGems installed. Once you have these technologies installed it's then really easy to install Capistrano:
gem install capistrano
Once you've got a project you want to use Capistrano with it's really easy to prepare the folder for use also - all you need to use from the source folder is:
capify .
This will then set the folder up to be used. Before you can use it though you will need to either configure the pre-defined commands or create your own. All the options available can be configured in a single file and you can specify pretty much any command-line tool you want which means the power of such a tool quickly becomes quite obvious.
set :application, "application-name"
set :repository, "/path/to/repository"
set :deploy_to, "/path/to/application"
set :deploy_via, "copy"
set :scm, :git
set :scm_checkout, "export"
role :web, "domain"
role :app, "domain"
role :db, "domain", :primary => true
set :user, "user"
set :use_sudo, false
set :ssh_options, {:forward_agent => true}
namespace :deploy do
task :update do
transaction do
update_code
symlink
end
end
task :finalize_update do
transaction do
run "chmod -R g+w #{releases_path}/#{release_name}"
# Create symbolic links to shared resources
run "ln -nfs #{shared_path}/bootstrap.php
#{releases_path}/#{release_name}/application/configs/bootstrap.php"
end
end
task :migrate do
# Override, we have no migrations
end
task :start, :roles => :app do
# Override but do nothing
end
task :stop, :roles => :app do
# Override but do nothing
end
task :restart do
# Override, no need to restart Apache
end
end
The above example is courtesy of Tom Graham and comes from his work in creating a Capistrano deployment method for the Zend Framework. I recommend checking this out, especially if you're interested in the Zend Framework, as it will help you understand the configuration of Capistrano.
There is a lot more you can do with deployment software like Capistrano though, you could create an interface for it from PHP or .NET scripts to create staging environments. One possibility I can see with this is a server with some SCM software installed and Capistrano could effectively allow you to version control your content with very little effort. Of course this does pose the problem of how you search over the content if it's version controlled in files, but on *nix based systems you could also reference the grep command line tool to return filenames of what you're looking for. If this is done in the right way so only live versions (possibly referenced to via a database mapping table) then what you've got is some very powerful version control. Translating this to Windows is not as easy, but with Cygwin installed it does open up the possibilities somewhat.
When it deploys a new version to the live server it seems to work based upon the modified timestamp of both the intended version, and the current live version, possibly so that any local changes on the live server are not overwritten by a deployment. I'm not totally certain this is the case though due to how the deployment works - it will upload each new version to a different folder and will then update a symbolic link to indicate which version should be used.
There are other solutions though, such as Fabric. The difference here is that the software is written in Python which means it may be more comfortable for those who are more familiar with Python than Ruby. The way it functions is quite similar to Capistrano in that you can create different configurations (called fabfiles) and can then run them on multiple servers. It's not so much a deployment tool per se, but more of a general purpose tool for managing multiple hosts.
Unfortunately due to technical problems there is no video or podcast update for this session, but hopefully normal service will resume with next month's session. Next month I'm planning on giving a talk at PHPEM on how to learn Cocoa from the perspective of a PHP developer - the reason for this is that since the rise in popularity of the "smart phone" a lot of web-based applications are also getting native applications created for them. If you're interesting in attending this talk it will be on November 5th 2009 somewhere in Leicester (most likely at Demontfort University).









