Good. Evil. Bratwurst.

Some Capistrano Recipes for Radiant

Posted on by arlen

I’ve been dipping my toes into the Radiant CMS lately (a side-effect of my love affair with Ruby on Rails) and have run into several interesting moments. On the assumption I’m not alone in that, I thought I’d share some of my favorite recipes for deploying a Radiant app to an Apache-Phusion Passenger combination.

As I look at my deploy.rb file I’m reminded of the old Tom Lehrer ditty, “Lobachevsky”:

I am never forget the day I first meet the great Lobachevsky.
In one word he told me secret of success in mathematics:

Let no one else’s work evade your eyes,
Remember why the good Lord made your eyes,
So don’t shade your eyes,
But plagiarize, plagiarize, plagiarize –
Only be sure always to call it please ‘research’.

So here is the result of my ‘research’ (where I remember where I got the code from, I will also quote the source; where I don’t remember, I apologize in advance):

First, there are the Passenger-specific recipes:

desc "Restarting mod_rails with restart.txt"
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
desc "Starting mod_rails with restart.txt"
task :start, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"

desc "stop task is a no-op with mod_rails"
task :stop, :roles => :app do

This code block is one of those I found so long ago I’ve forgotten where I picked it up from. Passenger is usually run in ‘production’ mode, which means the server needs to be restarted whenever a code change is mode. Rather than taking apache down, this a accomplished by “touch”-ing a file called “restart.txt” and when the server notes the change it reloads the code. This code block will do that, except when the no_release option is active (no_release after all means no changes have been made, so there’s no need to force a restart).

I put the same code in for “start” as for “restart”, not that it’s needed. I was just being anal about having a recipe for that; if I ever find I need that function (as opposed to restart) I’ll have to work out first of all if it’s possible even to do it in capistrano. Likewise with “stop;” the recipe is a placeholder for functionality I’ve never needed.

This next recipe came to me from Matt Darby who in turn got it from Darcy Laycock:

desc "Make sure there is something to deploy"
task :check_revision, :roles => [:web] do
unless `git rev-parse HEAD` == `git rev-parse origin/master`
puts ""
puts " \033[1;33m**************************************************\033[0m"
puts " \033[1;33m* WARNING: HEAD is not the same as origin/master *\033[0m"
puts " \033[1;33m**************************************************\033[0m"
puts ""


(when using, preface the deploy namespace with:
before "deploy", "deploy:check_revision"
so it runs before the deploy.)

The one qualm I have with this recipe concerns the “rev-parse” — when I get the time and inclination I’m going to look at using “ls-remote” instead. Not sure at the moment which way is “the right way” but this works so changing it isn’t high on my priority list.

The principle here is to stop me from wasting time. I’ve been working for days on some changes, and they’re committed to my local repo, but somehow I forgot to push the changes up to origin, but instead I just deploy. And I sit there waiting for the deploy to finish, only to find the new version has the same bugs as the old. This recipe checks the local repo against origin and if they’re not the same, drops you out of the deploy with a message that you forgot to push before deploying.

(I toyed with the idea of just automatically doing the push instead of the message, but decided that wouldn’t be a good idea, as I might need to do something else before/after the push, and even if not, typing one extra command line didn’t seem a huge penalty to pay for absent-mindedness. Feel free to disagree with me.)

I pulled this post-deploy recipe from the ehaselwanter-radiant-capistrano-extension:

after "deploy:cold", "deploy:radiant:bootstrap"
after "deploy:migrate", "deploy:radiant:migrate:extensions"
after "deploy:update" do
run "mkdir #{latest_release}/cache"
#run "cp #{latest_release}/config/database_eyecatch.yml #{latest_release}/config/database.yml"
run "chmod -R g+w #{deploy_to}"
run "[ ! -d #{shared_path}/assets ] && mkdir #{shared_path}/assets; true"
run "[ ! -d #{shared_path}/galleries ] && mkdir #{shared_path}/galleries; true"
run "[ ! -d #{shared_path}/uploads ] && mkdir #{shared_path}/uploads; true"
run "ln -s #{shared_path}/assets #{latest_release}/public/assets"
run "ln -s #{shared_path}/galleries #{latest_release}/public/galleries"
run "ln -s #{shared_path}/uploads #{latest_release}/public/uploads"

I’m using a few other recipes from that file as well, but I’m not convinced about them, and am still looking to revise/replace them, so I’ll not post them here.

Also, I’m rather interested in taking a peek at Giovanni Intini’s set of recipes but the link there doesn’t seem to work.

I’m still looking for useful recipes, so please point me to others, especially for bootstrap and migrations, as the ones I’m using aren’t yet reliable enough to publish.

2 Responses to Some Capistrano Recipes for Radiant

  1. Hi! Thanks for noticing the broken link 🙂

    This is the github repo of the radiant recipes:

    Pay attention though, because that’s old code (very) 🙂

  2. Thank you for the new link. I’ll stop by and check it out.

    Don’t worry about the “old code” part, though. I had to update a lot of the code I “researched” for my deploy. And I’ve changed it myself since I wrote this post. I’ll probably return to this topic after 3.0 ships with some updates.

    For example, I’ve since added “staging” as an environment for cap to use, which changes servers, so “cap staging deploy” goes to a different server than “cap production deploy” goes to.

    That’s the fun of Rails: things are constantly changing — so much so that sometimes even by the time they’re on the web they’re obsolete!

Leave a Reply

Your email address will not be published. Required fields are marked *

September 2009
« Aug   Jan »