Is there a way to use capistrano (or similar) to remotely interact with rails console

后端 未结 6 632
情话喂你
情话喂你 2021-02-03 11:50

I\'m loving how capistrano has simplified my deployment workflow, but often times a pushed change will run into issues that I need to log into the server to troubleshoot via the

相关标签:
6条回答
  • 2021-02-03 12:17

    Not necessarily the best option, but I hacked the following together for this problem in our project:

    task :remote_cmd do
      cmd = fetch(:cmd)
    
      puts `#{current_path}/script/console << EOF\r\n#{cmd}\r\n EOF`
    end
    

    To use it, I just use:

    cap remote_cmd -s cmd="a = 1; b = 2; puts a+b"
    

    (note: If you use Rails 3, you will have to change script/console above to rails console, however this has not been tested since I don't use Rails 3 on our project yet)

    0 讨论(0)
  • 2021-02-03 12:19

    The article http://errtheblog.com/posts/19-streaming-capistrano has a great solution for this. I just made a minor change so that it works in multiple server setup.

      desc "open remote console (only on the last machine from the :app roles)"
      task :console, :roles => :app do
        server = find_servers_for_task(current_task).last
        input = ''
    
        run "cd #{current_path} && ./script/console #{rails_env}", :hosts => server.host do |channel, stream, data|
          next if data.chomp == input.chomp || data.chomp == ''
          print data
          channel.send_data(input = $stdin.gets) if data =~ /^(>|\?)>/
        end
      end
    

    the terminal you get is not really amazing though. If someone have some improvement that would make CTRL-D and CTRL-H or arrows working, please post it.

    0 讨论(0)
  • 2021-02-03 12:20

    This is how i do that without Capistrano: https://github.com/mcasimir/remoting (a deployment tool built on top of rake tasks). I've added a task to the README to open a remote console on the server:

    # remote.rake
    namespace :remote do
    
    desc "Open rails console on server"
    task :console do
      require 'remoting/task'
    
      remote('console', config.login, :interactive => true) do
        cd config.dest
        source '$HOME/.rvm/scripts/rvm'
        bundle :exec, "rails c production"
      end
    end
    
    end
    

    Than i can run

    $ rake remote:console
    
    0 讨论(0)
  • 2021-02-03 12:27

    I found pretty nice solution based on https://github.com/codesnik/rails-recipes/blob/master/lib/rails-recipes/console.rb

    desc "Remote console" 
    task :console, :roles => :app do
      env = stage || "production"
      server = find_servers(:roles => [:app]).first
      run_with_tty server, %W( ./script/rails console #{env} )
    end
    
    desc "Remote dbconsole" 
    task :dbconsole, :roles => :app do
      env = stage || "production"
      server = find_servers(:roles => [:app]).first
      run_with_tty server, %W( ./script/rails dbconsole #{env} )
    end
    
    def run_with_tty(server, cmd)
      # looks like total pizdets
      command = []
      command += %W( ssh -t #{gateway} -l #{self[:gateway_user] || self[:user]} ) if     self[:gateway]
      command += %W( ssh -t )
      command += %W( -p #{server.port}) if server.port
      command += %W( -l #{user} #{server.host} )
      command += %W( cd #{current_path} )
      # have to escape this once if running via double ssh
      command += [self[:gateway] ? '\&\&' : '&&']
      command += Array(cmd)
      system *command
    end
    
    0 讨论(0)
  • 2021-02-03 12:31

    cap -T

    cap invoke                        # Invoke a single command on the remote ser...
    cap shell                         # Begin an interactive Capistrano session.
    

    cap -e invoke

    ------------------------------------------------------------
    cap invoke
    ------------------------------------------------------------
    Invoke a single command on the remote servers. This is useful for performing
    one-off commands that may not require a full task to be written for them. Simply
    specify the command to execute via the COMMAND environment variable. To execute
    the command only on certain roles, specify the ROLES environment variable as a
    comma-delimited list of role names. Alternatively, you can specify the HOSTS
    environment variable as a comma-delimited list of hostnames to execute the task
    on those hosts, explicitly. Lastly, if you want to execute the command via sudo,
    specify a non-empty value for the SUDO environment variable.
    
    Sample usage:
    
      $ cap COMMAND=uptime HOSTS=foo.capistano.test invoke
      $ cap ROLES=app,web SUDO=1 COMMAND="tail -f /var/log/messages" invoke
    
    0 讨论(0)
  • 2021-02-03 12:33

    I really like the "just use the existing tools" approach displayed in this gist. It simply uses the SSH shell command instead of implementing an interactive SSH shell yourself, which may break any time irb changes it's default prompt, you need to switch users or any other crazy thing happens.

    0 讨论(0)
提交回复
热议问题