Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@toobulkeh
Forked from benedikt/rails.rb
Created January 2, 2014 02:42
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save toobulkeh/8214198 to your computer and use it in GitHub Desktop.
Save toobulkeh/8214198 to your computer and use it in GitHub Desktop.
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
Copy link
Author

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
Copy link

umhan35 commented Jan 9, 2014

Is this for Rails 4?

@asok
Copy link

asok commented Jan 13, 2014

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

@bouchard
Copy link

bouchard commented Feb 2, 2014

Change the bad line to:

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

@phstc
Copy link

phstc 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
Copy link

dfang 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
Copy link

ream88 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
Copy link

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
Copy link

agirorn 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
Copy link

DmytroLukianov 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

@rannyeribaptist
Copy link

In case anyone still have issues with rbenv and @DmytroLukianov solution, I tuned it a bit and it worked for me:

namespace :rails do
  desc 'Start a rails console'
  # Usage: cap production rails:console
  task :console do
    on roles(:app) do
      exec "ssh #{host.user}@#{host.hostname} -p #{host.port || 22} -t 'cd #{current_path} && $HOME/.rbenv/bin/rbenv exec bundle exec rails console'"
    end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment