Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Updated for Capistrano 3.
# encoding: UTF-8
# Place in config/deploy.rb
namespace :rails do
desc "Open the rails console on each of the remote servers"
task :console do
on roles(:app) do |host| #does it for each host, bad.
rails_env = fetch(:stage)
execute_interactively "ruby #{current_path}/script/rails console #{rails_env}"
end
end
desc "Open the rails dbconsole on each of the remote servers"
task :dbconsole do
on roles(:db) do |host| #does it for each host, bad.
rails_env = fetch(:stage)
execute_interactively "ruby #{current_path}/script/rails dbconsole #{rails_env}"
end
end
def execute_interactively(command)
user = fetch(:user)
port = fetch(:port) || 22
exec "ssh -l #{user} #{host} -p #{port} -t 'cd #{deploy_to}/current && #{command}'"
end
end
@toobulkeh

This comment has been minimized.

Copy link
Owner Author

commented Jan 2, 2014

If someone wants to solve how to do this for just the first server of that role, that would be nice. Capistrano 3 is a huge improvement, but it's really quite hard to backwards engineer the rack application if you're not too familiar with rake or ruby. I even went so far as to check out the ObjectSpace in Ruby to figure out what was available to me...

@umhan35

This comment has been minimized.

Copy link

commented Jan 9, 2014

Is this for Rails 4?

@asok

This comment has been minimized.

Copy link

commented Jan 13, 2014

@toobulkeh I think that primary(:app).hostname should give the correct hostname.

@bouchard

This comment has been minimized.

Copy link

commented Feb 2, 2014

Change the bad line to:

on roles(:app), :primary => true do
@phstc

This comment has been minimized.

Copy link

commented Jun 15, 2014

How I'm doing:

cap [staging] rails:console   # connect to the first server
cap [staging] rails:console 1 # connect to the second server
namespace :rails do
  desc 'Start a rails console `cap [staging] rails:console [server_index default: 0]`'
  task :console do
    on roles(:app) do |server|
      server_index = ARGV[2].to_i

      return if server != roles(:app)[server_index]

      puts "Opening a console on: #{host}...."

      cmd = "ssh #{server.user}@#{host} -t 'cd #{fetch(:deploy_to)}/current && RAILS_ENV=#{fetch(:rails_env)} bundle exec rails console'"

      puts cmd

      exec cmd
    end
  end
end
@dfang

This comment has been minimized.

Copy link

commented Aug 8, 2014

@phstc, +1

i installed rbenv on my server by chef cookbook, i need to add 'source /etc/profile' before cd command. otherwise bundle command is not found.

thanks

@ream88

This comment has been minimized.

Copy link

commented Aug 29, 2014

In case you have the same setup as me (Rails 4.1.x, Ruby 2.1.x and rbenv) following will do it for you:

namespace :rails do
  desc 'Open the rails console on the primary remote server'
  task :console do
    on roles(:app), primary: true do |host|
      command = "/home/#{host.user}/.rbenv/shims/ruby #{deploy_to}/current/bin/rails console #{fetch(:stage)}"
      exec "ssh -l #{host.user} #{host.hostname} -p #{host.port} -t 'cd #{deploy_to}/current && #{command}'"
    end
  end
end
@chrisbloom7

This comment has been minimized.

Copy link

commented Dec 10, 2014

Here's what I found worked with Rails 4.1, Ruby 2.1, and RVM with the capistrano-rvm extension

namespace :rails do
  desc "Open the rails console on each of the remote servers"
  task :console => 'rvm:hook' do
    on roles(:app), :primary => true do |host|
      rails_env = fetch(:stage)
      execute_interactively host, "console #{rails_env}"
    end
  end

  desc "Open the rails dbconsole on each of the remote servers"
  task :dbconsole => 'rvm:hook' do
    on roles(:app), :primary => true do |host|
      rails_env = fetch(:stage)
      execute_interactively host, "dbconsole #{rails_env}"
    end
  end

  def execute_interactively(host, command)
    command = "cd #{fetch(:deploy_to)}/current && #{SSHKit.config.command_map[:bundle]} exec rails #{command}"
    puts command if fetch(:log_level) == :debug
    exec "ssh -l #{host.user} #{host.hostname} -p #{host.port || 22} -t '#{command}'"
  end
end

Gist: https://gist.github.com/chrisbloom7/5de890debc104390d6d4

@agirorn

This comment has been minimized.

Copy link

commented Jan 29, 2015

What about running it just on the first available host.

namespace :rails do
  desc "Open the rails console on each of the remote servers"
  task :console do
    on roles(:app).first do |host| #does it for the first host.
      rails_env = fetch(:stage)
      execute_interactively "ruby #{current_path}/script/rails console #{rails_env}"  
    end
  end

  desc "Open the rails dbconsole on each of the remote servers"
  task :dbconsole do
    on roles(:db).first do |host| #does it for the first host.
      rails_env = fetch(:stage)
      execute_interactively "ruby #{current_path}/script/rails dbconsole #{rails_env}"  
    end
  end

  def execute_interactively(command)
    user = fetch(:user)
    port = fetch(:port) || 22
    exec "ssh -l #{user} #{host} -p #{port} -t 'cd #{deploy_to}/current && #{command}'"
  end
end
@DmytroLukianov

This comment has been minimized.

Copy link

commented Jul 27, 2017

For rbenv:

namespace :rails do
  desc "Open the rails console"
  task :console do
    on roles(:app) do
      rails_env = fetch(:rails_env, 'production')
      execute_interactively "$HOME/.rbenv/bin/rbenv exec bundle exec rails console #{rails_env}"
    end
  end

  desc "Open the rails dbconsole"
  task :dbconsole do
    on roles(:app) do
      rails_env = fetch(:rails_env, 'production')
      execute_interactively "$HOME/.rbenv/bin/rbenv exec bundle exec rails dbconsole #{rails_env}"
    end
  end

  def execute_interactively(command)
    user = fetch(:user)
    port = fetch(:port) || 22
    exec "ssh -l #{user} #{host} -p #{port} -t 'cd #{deploy_to}/current && #{command}'"
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.