Skip to content

Instantly share code, notes, and snippets.

@toobulkeh
Forked from benedikt/rails.rb
Created January 2, 2014 02:42
Show Gist options
  • Select an option

  • Save toobulkeh/8214198 to your computer and use it in GitHub Desktop.

Select an option

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
@bouchard
Copy link
Copy Markdown

bouchard commented Feb 2, 2014

Change the bad line to:

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

@phstc
Copy link
Copy Markdown

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

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

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

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

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

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

@rannyeribatista
Copy link
Copy Markdown

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