Puppet vs. Capistrano – a short comparison

We’re currently using Capistrano not only to deploy our Ruby on Rails application, but also to setup and manage our physical and virtual (Xen based) servers. We have Capistrano recipes for adding users, installing packages like apache or mysql, configuring a Xen VM and more. Coming accross puppet, I started to wonder about the essential difference between the two. Puppet claims to enable the user to automate server management to a large extent, a goal which we already reached by implementing our custom Capistrano recipes. So, what are the differences between the two?

Overall Goal

First, I tried to understand the overall goal of both tools. Capistrano was built with deployment of rails applications in mind. Of course, it is very easy to extend it to manage your servers like we did, and recipe collections like deprec add exactly that functionality to it, but still, the basic problem Capistrano adresses is deployment.

Puppet on the other hand started as a lifecycle management tool from the beginning. It offers a lot of possibilities to define dependencies and desired states of services like apache should be running and needs this and that package additionally to those config files. Puppet then tries everything to reach that desired state automatically. This difference in the overall goal leads us to the different approaches both tools are using.


Capistrano uses an imperative approach where you describe in recipes how to do things. Looking at Capistrano recipes gives you a kind of “dynamic” view on your systems. You can see how a specific configuration evolves step by step. The recipes answer the questions “What do I want to do”?

Puppet uses a declarative approach where you describe a desired state for your system configuration. Your manifests answer the question: “How should it look like”? Puppet derives the steps to take from the static configuration and applies them as needed automatically.

Feature Comparison

Here is a short comparison matrix showing some features I found interesting. It is by far not complete, but I hope it might give you an overview:

Puppet Capistrano
Configuration language ”Meta” language Ruby
noop mode yes yes (since 2.5)
Idempotence yes no
Transactions yes yes
Rollback no yes
Ad-hoc server monitoring no yes
Mode of operation deamon pulls config user pushes changes
Dependency definition Dependency trees with services, packages, and files Single dependencies for dir, writability, command, gem and regex match
Dependency resolution automatically manually


Puppet acts on a different level than Capistrano dealing mostly with managing dependencies rather than scripting tasks. Puppet and Capistrano can play nicely together in a scenario where puppet is responsible for ensuring a certain system configuration and Capistrano is responsible for the more dynamic aspects like deploying new releases of your custom applications or ad-hoc server monitoring. But as my own experience and the success of deprec shows, Capistrano is a great help for configuring systems, too.

10 thoughts on “Puppet vs. Capistrano – a short comparison

  1. Like your blog, stumbled on the Agile one and then, whoa, Puppet.
    With Puppet rollback is a feature that we hope to add eventually to the framework, but for now, since Puppet is declarative code (which I hope you have in version control) a roll back is just reverting the code and running Puppet again.
    Also with Capistrano, you don’t get generalized rollback and transactions on server management tasks unless you roll them all by hand yourself. Capistrano has a lot of scaffolding for deploying rails where this is built in, but after than you are sort of on your own.


  2. @Andrew
    > but for now, since Puppet is declarative code (which I hope you have in version control) a roll back is just reverting the code and running Puppet again.

    See I’ve seen that said over and over in Puppet docs and tutorials but I don’t see how it’s true in many cases. If I declare that a package should be installed, a serive started, or a certain file should be overwritten with a customisation; then rolling back to before I added that declaration does not stop the service, does not remove the package and does not delete the config if it didn’t exist before puppet created it. I don’t think Puppet does itself any favors by claiming to be able to rollback chages meerly by adding version crontrol. There is a lot more to it than this.


Leave a Reply to Andrew Shafer Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.