So Jamis Buck has been hard at work on a new version of Capistrano, the deployment and automation tool for any task that a sysadmin could possibly imagine doing on a server.
There’s a new website and also the start of a wiki. There is a new engine that separates the parts so they can be used independently.
There are also a few changes that break existing recipes. No worries…they are easy to fix. Here’s how I did it.
Install the pre-release gem. You might need to get Highline first.
sudo gem install highline sudo gem install -s http://gems.rubyonrails.com capistrano
Tell Capistrano install the new Capfile in your Rails application.
$ cd my_rails_app $ capify .
Any external task libraries will probably be incompatible with Capistrano 2. I commented them all out and started from scratch (although the authors will probably update them in the next few weeks).
# require 'railsmachine/recipes'
# require 'deprec/recipes/cache_svn'
# require 'vmbuilder/plugins'
Some are actually included in the main distribution now, like Chris McGrath’s recipe that updates a cached copy of your code on the server. It’s now available with this setting:
set :deploy_via, :remote_cache
If you don’t already have a cached copy on the server, it will make one for you in shared/cached-copy. Subsequent deployments will just do an svn update on that directory instead of doing a full checkout every time. A fresh copy is then copied into the releases directory. This is a much faster way to deploy and I use it on every one of my deployments.
Note: If you were using this technique before, you can use the old repository_cache variable and it will work as expected.
set :repository_cache, "#{shared_path}/svn_trunk/"
set :deploy_via, :remote_cache
default taskNamespaces are nice, but they will break older recipes that use callbacks such as after_deploy. There’s now a default task inside the deploy namespace that you can use instead.
I wrote a simple callback that runs the cleanup task after every deployment.
namespace :deploy do
desc "Run this after every successful deployment"
task :after_default do
cleanup
end
end
Other callbacks work the same way. Just put them inside your namespace and they will work normally.
namespace :deploy do
task :after_update_code do
# ...
end
task :before_symlink do
# ...
end
end
One thing I haven’t figured out yet is how to call tasks in another namespace. For now, you can just call local tasks as methods as usual. See the call to cleanup above.
For this blog I have a special deployment file that just updates the theme and clears out the cache. I can still deploy with cap deploy, but it skips update_code, symlink, and the other steps.
For that, I just override the deploy:default task.
namespace :deploy do
desc "Update the theme and delete cached files."
task :default do
# Call custom tasks in this namespace
update_theme
sweep_cache
end
task :update_theme do
# ...
end
end
My first few deployments failed because there was no shared/pids directory to link to from the current/tmp/pids directory. In fact, that directory didn’t exist, either.
I ran the deploy:setup task and added empty tmp directories to svn. There are now directories that can be properly linked to.
Bradley Taylor is probably fixing this right now, but until the next mongrel_cluster gem is released, you can restart mongrel with this task:
set :mongrel_config, "/etc/mongrel_cluster/#{application}.yml"
namespace :deploy do
task :restart do
sudo "mongrel_rails cluster::restart -C #{mongrel_config}"
end
end
If you want to learn more about Capistrano, check out the PeepCode episode on the topic. It will be updated for Capistrano 2 after the official release and will be a free update for anyone who bought it previously.
The new Rails Podcast with Zed Shaw already has people rolling in the aisles with laughter, amazement, and hate.
This blog is now running on nginx from top to bottom with Rails and PHP running side by side. Some of my notes and scripts are available.
I had the honor of being interviewed by Fabio Akita (also in Brazilian Portuguese).
Travels are hardly over before they start again. I’ll be speaking at RailsConf in Portland in May, Ruby en Rails in Amsterdam June 7 (no website available yet), and Ostrava on Rails in the Czech Republic June 22-23.
And thanks to the incredible support of the Ruby community, I’ll be going fulltime on PeepCode Screencasts next month! I’m putting the final coat of wax on the next episode (Javascript with Prototype, together with Justin Palmer).
Thanks for the tips!
Not sure which Chris you’re trying to refer to in the “Comment out all external libraries” section, but you reference Chris Wanstrath (http://errtheblog.com) but link to Chris McGrath (http://octopod.info/).
Congrats on going full-time with the Peep!
See, that’s the benefit of having a link and a title…you’re bound to get at least one of them correct!
I was actually referring to Chris McGrath and have fixed it now.
1) Congrats on Full Time with Peepcode!
2) The last Ruby on Rails podcast interview was great for sure!
3) Freely updating Capistrano peepcode to version 2 for those who already paid is a demostration of the type of service that everyone should pay attention to!
I just got through with Peepcode’s REST screencast and I posted a review on Lulu. Great stuff Geoffrey! I’ll definitely be checking out more Peepcode videos in the future! And congrats on going full time with it!
Say you have a namespace
infoand a taskhttpd_mem:namespace :info do desc "Get top 5 httpd processes by real memory usage" task :httpd_mem, :roles => [:web, :stats, :cms] do run <<-CMD ps axcmo pid,rsz,command | grep httpd | awk '{LIMIT = 1; if ($2 > LIMIT) printf $2/1024 " MB\n"}' | sort -rn | head -n5 CMD end endTo execute that task in another namespace:
namespace :whatever do task :httpd_mem do info.httpd_mem end end@Jesse: Awesome. Thanks for the explanation.
For those wanting to have a look at a mongrel_cluster recipe for cap 2.0, here is the recipe file.
Note the use of ‘before’ and ‘after’ callbacks and also the ‘depend’.
I also, override the “deploy:setup” task as I assume you are using the “mongrels” as your app servers.
I recently created a recipe for cap 2 that deploys Mint using some code from your post on the Mint forums. I wanted it to be tied a bit tighter with the app itself.
Hopefully somebody can set me straight if I’m way off base, but it’s working well for me.
Older tasks not in any namespace will still work, such as :before_deploy and :after_deploy. In this article Jamis mentions that they will be deprecated in the future.
Older tasks not in any namespace will still work, such as :before_deploy and :after_deploy. In this article Jamis mentions that they will be deprecated in the future.
I’ve put together a Rails plugin called “Capistrano Bells” that gives you a collection of Capistrano 2 recipes to use while developing and deploying your app. My main focus was to take the parts of the deprec gem that I missed most and make the Capistrano 2 friendly.
It’s my first attempt at a Rails plugin, and it’s still not totally finished. Still, I was able to use it to deploy a new project, and it worked well enough.
If you’re interested, you can check it out here: Introducing: Capistrano Bells
looks like you can call the name space as an object, and the task as a method.
so you can call deploy.migrate outside the :deploy namespace
cheers,Jodi
looks like you can call the name space as an object, and the task as a method.
so you can call deploy.migrate outside the :deploy namespace
That doesn’t work for me…namespace :deploy do task :after_cold do web.restart end end namespace :web do task :restart, :roles => :web do default_run_options[:pty] = true # or else you'll get "sorry, you must have a tty to run sudo" sudo "/etc/init.d/httpd restart" end endresults in…Using Capistrano 2.1.0.
great work, going to try upgrading to Capistrano 2 when they finally release Deprec 2
all the best,
John.
About restarting mongrel, just put require ‘mongrel_cluster/recipes’ on the top of your deploy.rb and set you mongrel_conf variable !