Sean’s Obsessions

Sean Walberg’s blog

Understanding Capistrano Hooks and Deploy vs Deploy:migrations

Capistrano is a deployment framework for Rails, though it can be extended to do pretty much anything. The system comes with a bunch of built in tasks, and each task can be made up of other tasks and code. Plugins can add their own tasks and hook into default tasks, and the user can do the same through the configuration files.

Like any popular open source project capistrano has gone through changes. Documentation on the Internet is plentiful but often refers to old ways of doing things, so copy/pasting recipes can often result in stuff that doesn’t work quite right.

One common thing people need to do is to run some command after the deploy or at some time during the deploy. Capistrano has a very easy way of doing this.

1
after 'deploy:update_code', 'deploy:symlink_shared'

This says “after running deploy:update_code, run deploy:symlink_shared”. The latter is custom task that’s defined elsewhere.

The problem comes in when you look at the way the “deploy” and “deploy:migrations” tasks differ. I’ve seen a common problem where something works when deploying without migrations but not when migrations are used. Usually this is because the hook used is not the right one, either because of bad information or the user figured out where to hook into by looking at the output of a deploy.

If you look at Capistrano’s default deploy.rb you can piece together the tasks that are run in both cases.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
deploy:migrations
  update_code
   strategy.deploy!
   finalize_update
  migrate
  create_symlink
  restart
deploy
  update
    update_code
      strategy.deploy!
      finalize_update
    create_symlink
  restart

From this, you can see that the sequence is somewhat different. The “update” task isn’t used in the migrations case. Instead, the components are replicated.

If you want to hook in, use

  • update_code to run before/after the code is put into the release directory, such as if you want to make more symlinks or do something before migrations are potentially run.
  • create_symlink to run before/after the symbolic link pointing to the current release is made. Note that symlink is deprecated. You can run it from the command line, but if you try and hook in to it, you won’t be happy.
  • restart to run before/after the application server is restarted, e.g. to restart background workers or do deployment notifications

Comments

I’m trying something new here. Talk to me on Twitter with the button above, please.