Rails 3 – Bundler – Dreamhost – Capistrano

Problem
You want to deploy your Rails (3.0.3) application to Dreamhost using Capistrano, but you get errors like:

bundle command not found
or
Enter your password to install the bundled RubyGems to your system:

Solution
You may be able to see in your deploy.rb file a commented section that says the following:

As Capistrano executes in a non-interactive mode and therefore doesn’t cause
any of your shell profile scripts to be run ….

So in order for capistrano to be able to find your bundle command you should add in your deploy.rb file a line with your paths (ie):

default_environment['PATH']='/usr/lib/ruby/gems/1.8/bin:/home/your_name/.gems/bin:/usr/local/bin:/usr/bin:/bin'

If you have the previous line your bundle command can run, but if you try to do cap:deploy your bundler will probably give you an error as it would ask for your sudo password. In order to avoid this error and to make it work you have to add another line with your gem path (ie):

default_environment['GEM_PATH']='/home/your_name/.gems:/usr/lib/ruby/gems/1.8'

making sure that your home directory path for your gems is first in the list.

capistrano deployment fails after dreamhost server move

Problem
You have set up your capistrano recipe for deployment to dreamhost using password less logins, but after dreamhost moves your git repository server to a different server, the deployment breaks, with ‘permission denied’ when trying to get the git repository.

Solution
As the server was moved you would need to copy your ssh public key from the deployment server to the new server again for the password-less logins to work again.
Follow the details here how to copy your public key across, login in once with your password, and after that your capistrano recipe should be working again as normal.

Deploying a Rails project in a server that hosts the git repository

Problem
You want to deploy your project in a server (dreamhost), that also hosts your git repository. When you try to do that by only setting the set_repository, you get errors like ‘permission denied, please try again’, even though if you try to checkout the git repository on your server works.

Solution
Set your :repository as a file in your host as in:
set :repository, "file:///home/username/git_on_server/projects/repo_name.git"

Then also set up your local_repository, as in:
set :local_repository, "user_name@server_domain_name:/home/username/git_on_server/projects/repo_name.git"

RubyGem version error: rack(0.3.0 not ~> 1.0.0)

Problem
Trying to deploy in dreamhost with capistrano you get the error:

RubyGem version error: rack(0.3.0 not ~> 1.0.0)

Solution
Log in with ssh to your dreamhost account and then install the newer version of rack that is not yet installed in dreamhost:

gem install rack

That assumes that you have followed the instructions for setting up your local gems in dreamhost (here) and you already have a ~/username/.gems directory.

You may probably need to also add the following to your config/environment.rb :

ENV[‘GEM_PATH’] = ‘/home/USERNAME/.gems’

Note 09-Sep-2009
It seems that according to the dreamhost wiki we need to add the following to the config/environment.rb, instead of the line above:

if ENV[‘RAILS_ENV’] == ‘production’
ENV[‘GEM_PATH’] = ‘/home/USERNAME/.gems’
require ‘/home/USERNAME/.gems/gems/rack-1.0.0/lib/rack.rb’
end

to use the locally installed rack-1.0.0 gem, instead of the rack installed by dreamhost.

Dreamhost, Rails 2.1.1, Freeze, Capistrano

Problem
With the imminent upgrade in Dreamhost to Rails 2.1.1 (dreamhost blog post here), you may want to freeze your Rails version to a previous version, using capistrano.

Solution
On your local development pc freeze the rails:

rake rails:freeze:gems

Add the new code to your svn repository:

svn commit -m 'freeze rails'

And then deploy to dreamhost using capistrano:

cap deploy

Your rails project located on dreamhost should be frozen to your current Rails version.

Developing in Rails 2.1 and deploying in Rails 2.0.2 (or error – undefined method time_zone)

Problem
You are developing on the latest version of Rails (2.1), but your production server for deployment uses version 2.0.2 (as dreamhost is using at the moment).

Solution

  1. First change the environment.rb file to use the rails version in your deployment server
    RAILS_GEM_VERSION = '2.0.2' unless defined? RAILS_GEM_VERSION
    
  2. You should probably be geting the error: undefined method = time zone by now, so make sure you comment out from further down your environment.rb file the line:
    config.time_zone = 'UTC'
  3. Some further errors would be caused by the file config/initializers/new_rails_defaults.rb, so make sure you comment out the following lines:
    ActiveRecord::Base.include_root_in_json = true
    ActiveRecord::Base.store_full_sti_class = true
    ActiveSupport.use_standard_json_time_format = true
    ActiveSupport.use_standard_json_time_format = true

You should be able to deploy and use your application now.

Disabling rails web site when using mongrel,Apache,capistrano 1.4.1

Problem
You want to disable your rails web site for maintenance, but your application uses an older capistrano version than the one currently installed.

Solution
According to the RubyOnRails Cookbook recipe 13.12, it should only be a case of running cap disable_web (enable_web).
But in the meantime you have upgraded your capistrano version to version 2, and started using mongrel server as well.
So if you are using virtual severs and proxy with mongrel, the first thing to do is add the following in your Apache configuration file:

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /system/maintenance.html [R]

If you needed to make the above change then you will have to restart apache in your server.

Then in your local pc you can run the following:

export REASON="Maintenance for MySQL upgrade"
export UNTIL="Sat May 10 15:30:00 2008"
cap _1.4.1_ disable_web (to put it in maintenance)
cap _1.4.1_ enable_web (to restart it again)

Using older Capistrano version 1.x after upgrading to Capistrano 2.x

Problem
You have just upgraded your Capistrano installation to version 2.x, but you didn’t have time to convert your recipes to the newer version.

Solution
In order to be able to use your old recipes of Capistrano version 1.x after upgrading, you can use the following (assuming your version 1.x is 1.4.1):

cap _1.4.1_ deploy

or, if you have migrations you want to use:

cap _1.4.1_ deploy_with_migrations

Keeping uploaded files between deployments

Problem
You are using file_column plugin (or maybe another plugin?), to upload files in your ruby on rails application. Because the files are big you don’t want to have a different copy stored in your subversion repository for each different deployment version. You want to keep a common folder with all your uploaded files, and use it with every different deployment version.

Solution
For the example, we will have a numbers table that has two file_column uploadable columns (intro,voice_mail), with the following migration:

class CreateNumbers < ActiveRecord::Migration
  def self.up
    create_table :numbers do |t|
      t.column :customer_id, :int, :null => false
      t.column :phone_no, :string, :null => false
      t.column :intro, :string
      t.column :vmail, :string
      t.column :created_at, :datetime
      t.column :updated_at, :datetime
    end

  def self.down
    drop_table :numbers
  end
end
  1. If you already have used cap deploy or cap setup you should have a shared folder in your deployment server.
    You should copy the intro and vmail folders that should be located on your public/number folder on your local development client, on a folder called number in your development server in your shared folder.
  2. Create a file in your local pc in lib/cap_recipes.rb:
    Capistrano.configuration(:must_exist).load do
    
      desc "Keep generated uploaded files between deployments"
        task :after_symlink do
           run "rm -drf #{deploy_to}/#{current_dir}/public/number"
           sudo "ln -nfs #{shared_path}/number #{deploy_to}/#{current_dir}/public"
        end
      end

    Be careful with the naming of the task as (at least for capistrano 1.4 that I’m using), it must have a special name as after_symlink.
    Also be careful that if you try to use before_symlink, it won’t work as the current symlink won’t be setup.

  3. In your config/deploy.rb file add at the top the following:
    require 'lib/cap_recipes'
  4. Now you should be ready to deploy your new version so:
    svn -m "added customised capistrano recipes" commit

    make sure that you check in your version in subversion, and then:

    cap deploy

    you should be able to see a link in your current/public folder called number that points to the shared/number folder that hold all the uploaded files.