console-for opens a Rails console remotely on a Capistrano deployment target

We're adding a script console-for to open a remote Rails console with one command. Also have a look at shell-for, which this script is relying on.

Run it from any project directory like this, passing a Capistrano multistage deployment target:

console-for staging

This script is part of our geordi gem on github.

Dynamically skip Capistrano hooks

When you have a hook in your Capistrano file that dumps your remote database, you might not want it to dump each time you deploy (say, you're experimenting with staging and don't want ten dumps an hour). How to skip dump creation:

Capistrano 2

In your Capistrano file:

before 'deploy:update_code', 'db:dump' unless fetch(:skip_dump, false)

The second parameter of fetch sets a default value if skip_dump is not defined.

In your terminal:

cap staging deploy -S skip_dump=true

The -S must be a capital letter t...

Script to create and copy a production dump to your project root

Soon after having written our shell-for script, we wanted to easily get dumps of our productions machines, too. This is how we do it:

dump-for staging [-s]

It will copy the dump to your project's tmp directory and name it according to the capistrano stage you're calling for, here: staging.dump. When you pass the optional -s option, the dump will automatically been sourced into your local development database.


This script ...

Script to open an SSH shell to a Capistrano deployment target

We regularly need to connect to the server in order to e.g. access the production console. Guessing the Capistrano deploy user and then again guessing the right directory on the server is awkward, so we wrote a script that parses config/deploy and gives you the handy command shell-for.

Run it from any project directory like this, passing a Capistrano multistage deployment target:

shell-for staging

Now it also supports commands to be remotely executed before loading the bash. Use --no-bash to only execute the command and load no ba...

Putting static content on Cloudfront

We recently decided to put static content for HouseTrip.com to Amazon Cloudfront for a faster user experience. This happens fully automatically on deploy and is transparent in development. Together with a heavy use of sprites this sped up page load time quite nicely.

These are a couple of the problems you need to solve in order to do this:

  • There is no good way to invalidate Cloudfront cached assets, and Cloudfront will ignor...

Speed up Capistrano deployments using a remote cached copy of repository

You can seriously speed up deployments with Capistrano when using a local git repository on the server you are deploying to.

Simply add

set :deploy_via, :remote_cache
set :copy_exclude, [ '.git' ]

to your config/deploy.rb and Capistrano will create a clone in shared/cached-copy. This will be updated using git pull when deploying which transfers less bytes and is usually much faster. If deploy_via is set to use default settings (being "export"), Capistrano will do a full clone of the repository from your git host otherwi...

Capistrano 2: Which Capistrano hooks to use for events to happen on both "cap deploy" and "cap deploy:migrations"

When deploying an application with "cap deploy" by default [1] you only deploy your code but do not run migrations. To avoid an application to be running with code which requires database changes that did not happen yet you should use cap deploy:migrations.

The problem

Let's say that you have something like that in your config/deploy.rb to create a database dump every time you deploy:
before 'deploy', 'db:dump'
This will not be called for cap deploy:migrations. The same applies to other things that are hooked s...

Fix Capistrano with RubyGems 1.6

After updating your RubyGems, you will probably not be able to run Capistrano any more, but receive an error similar to this:
can't activate net-ssh (= 2.0.22) for [], already activated net-ssh-2.1.0 for [] (Gem::LoadError)

If you have Bundler installed, you can use bundle exec to avoid this problem as follows:

Create a gemfile at ~/.capistrano/Gemfile (or at some other sensible place), that only contains these 2 lines:
source 'http://rubygems.org'
gem 'capistrano'
gem 'capistrano-ext' # You need this for multistag...

Deploy and migrate with a single Capistrano command

Note that this sounds good but is not good at all when hooking tasks on cap deploy (see this article). Make sure to hook your calls properly when using this.


To deploy an application and run all pending migrations before restarting it, you can use the following standard Capistrano task:

cap deploy:migrations

Little is known what happens when the deployment goes through, but a migration or a rake task aft...

Show the description of a Capistrano task

In order to bring up a textual description of a Capistrano task you can say

cap -e taskname

... where taskname is the name of the task you're not sure about.

Allow a user to run a single command with root privileges

It's that simple to allow one of your Linux users to run a single command as UID 0:

  1. sudo visudo
  2. Add the line below to allow user 'deploy' to run /usr/bin/bundle with root privileges
deploy  ALL=NOPASSWD: /usr/bin/bundle

Apply a new callback to existing records

So you added a new callback to your model that (e.g.) caches some data when it is saved. Now you need to run that callback for the 10000 existing records in the production database. You have two options here:

  1. Write a clever migration, possibly by embedding the model into the migration script.
  2. Open the Rails console after deployment and re-save every single record. You should probably add two chores to [Pivotal Tracker](http://www.pivotaltrac...

Use Sass without Rails

You don't need a Rails application to use Sass. Even when you're working on a static site you can generate your CSS through Sass.

  • Install Sass with sudo gem install haml
  • Create a folder sass in the folder, that stores your stylesheets, e.g. mkdir css/sass
  • In a separate terminal window, run sass --watch css/sass:css. This will watch your sass files for changes and rewrite stylesheets as required.

This even works on Windows.

Note about your .gitignore

You might want to change our [typical .gitignor...

Deliver Paperclip attachments to authorized users only

When Paperclip attachments should only be downloadable for selected users, there are three ways to go.
The same applies to files in Carrierwave.

  1. Deliver attachments through Rails

The first way is to store Paperclip attachments not in the default public/system, but in a private path like storage inside the current release. You should prefer this method when dealing with sensitive data.

Make ...

Bundler for Rails 2.3.x

Update RubyGems and Passenger

Bundler requires Rubygems >= 1.3.6. Run gem update --system if you have an older version.
It also is not compatible with older versions of passenger, so bring that up to date as well (2.2.15 works).

If you installed RubyGems through apt (which you should never do!), you may see a message giving you a hint to use apt to update.
Some people advise to install the 'rubygems-update-1.3.7' gem on Ubuntu systems if you used apt to install RubyGems.
I did that - and lost all...

Change Paperclip secrets the hard way

So you screwed up and copied Paperclip secrets from one project to another. Here is a semi-automatic, painful way to migrate your existing attachment files to new locations.

You need to follow this step by step, do not just copy the whole thing into the console!

# 1. Get old paths by doing something like this on the console:
old_paths = ModelWithAttachment.all.collect { |m| [m.id, File.dirname(m.image.path(:original)).gsub(/original$/, '') ] if m.image.file? }.compact.uniq

# 2. Now change the Paperclip secret on the co...

Release gem; Deploy gem; Update a gem created with Jeweler

Until May 2011 our gems have been created with Jeweler, which is a helper library to package code into a gem. You know a gem was cut with Jeweler if you see the word jeweler in a gem project's Rakefile.

This note describes how to update a gem that was cut using Jeweler. Note that this can be traumatic the first time. It would be great to have an easier workflow for this. Jeweler is deprecated these days because you can

**now [cut gems more easily using Bundler](https://makandracards.com/makandra/1229-updat...

How to fix "Too many authentic authentication failures" with SSH and/or Capistrano

You are getting when connecting via SSH or deploying with Capistrano (which uses SSH):

Too many authentication failures for username

This is caused by having too many SSH keys added to your keyring or ssh-agent. Your ssh-agent will throw all keys against a server until one matches. Most servers will deny access after 5 attempts.

This issue might come and go as the order of the active SSH keys in your ssh-agent changes.

Quick fix

Have less keys. Up to 5 keys are fine when the SSHD you're connecting to is using the default ...