Deploying a CakePHP app with Capistrano
Deploying a CakePHP app with Capistrano
During my internship i was working on a large project and at the end of the process it became more and more difficult to keep the development version and the live version in sync while maintaining different configurations.
A couple of colleagues used Capistrano for their Rails projects and i tried to modify Capistrano so that it would work with CakePHP.
Password-less login
First we need to be able to login without providing a password this guide from Brian Rosner describes the steps to do this.
The reason for this password-less login is that you don’t have to provide a password when you deploy this way.
Capistrano
Next we need to get Capistrano. I work on a mac with OSX 10.5, witch has Capistrano built-in. If you have never updated this version of capistrano you might want to gem update your version.
Folder structure

The image above shows my folder structure. The current folder is actually a symlink to the latest deploy of my project. The logs is for my apache access and error logs and the releases folder contains the latest 10 releases deployed to the server.
The shared folder contains files and folders that i want to use instead the ones i deploy. In my case i keep the /app/config folder here.
Capfile
In the root of my project folder i created a capfile (no extension)
that contains the following code:
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
role :web, 'example.com'
ssh_options[:username] = 'notrootofcourse'
ssh_options[:forward_agent] = true
set :scm, :git
set :scm_verbose, true
set :repository, 'git@git.example.com:repository'
set :branch, 'master'
set :deploy_via, :remote_cache
set :use_sudo, false
set :application, 'application_name'
set :deploy_to, "/data/webservers/#{application}/"
namespace :deploy do
task :start do
end
task :stop do
end
task :restart do
end
desc <<-DESC
Symlinks shared configuration and directories into the latest release
Also clear persistent and model cache
DESC
task :finalize_update do
run "rm -rf #{latest_release}/app/config; ln -s #{shared_path}/app/config #{latest_release}/app/config"
run "rm -rf #{latest_release}/app/tmp/models/*"
run "rm -rf #{latest_release}/app/tmp/persistent/*"
end
end
namespace :tail do
task :default do
run "tail -f #{deploy_to}/logs/*.log"
end
end
The first lines of the Capfile set some global configuration options, like your ssh username that can login without providing a password, the (in my case git) repository to pull the latest release from and the name and path of the application.
To make capistrano work with (Cake)PHP you need to overwrite all the default tasks that capistrano runs when deploying. Since i use apache and php, we don’t need to restart the webserver, so we just create a :restart task that does nothing, the same goes for :start and :stop
in the :finalize_update task i link the /config dir of my CakePHP app to the shared folder i described above. This way i always use the live configurations instead of my dev configs. Also, just to be sure, i remove the cached data.
All there is to do is a “cap deploy” in the root folder of your project and capistrano will deploy the latest version to your server.
This is of course just a simple example of a capistrano config and you can create your own folder structure and run your own commands.
Besides deploying i also created a :tail namespace, witch tails my log files. This way i can do a “cap tail” to see what’s going on with apache without logging in trough ssh. Other possible functions could be a “cap clearcache” to remove all the cache files.

