SSH从Heroku的与MySQL数据库远程服务器(SSH from Heroku into rem

2019-10-21 03:44发布

我在看一个Rails应用程序将需要为背景,ActiveRecord的会话的一部分建立从Heroku的远程SSH会话(SSH隧道?)到远程MySQL数据库。 目标将是通过该通道进入该应用迁移在不同时间的数据。 通过网络连接到远程MySQL数据库不会是一个选项。

几个问题:

  1. Heroku上是否允许ssh方式连接了他们的迪诺?
  2. 什么是这样做的缺点?
  3. 我将不得不担心SSH会话持久性(工作可能需要1小时)?
  4. 最后,我怎么可以配置Rails和Heroku上启用一个database.yml的mysql的端点远程连接?

Answer 1:

好了,我现在可以四处寻找了几天后,回答我的问题。 总之,是的。

class LegacyAccount < ActiveRecord::Base

 self.table_name = "account"

 def self.test_connection

      # net-ssh-gateway gem
      gateway = Net::SSH::Gateway.new("ip_address","ssh_user_name",
          password: "password",
          port: "port if different from 22",
          verbose: :debug
          )

      port = gateway.open('127.0.0.1', 3306, 3307)

      establish_connection :legacy_production

      result = LegacyAccount.first
      puts "Record: #{result.to_yaml}"

      gateway.close(port)
      gateway.shutdown!

      result
  end

end

并在您的database.yml:

legacy_production:
  adapter: "mysql2"
  host: "127.0.0.1"
  username: "root"
  password: "password"
  database: "legacydb"
  port: 3307
  secure_auth: false


Answer 2:

我试图@ user1322092的做法和陷入困境时,多个客户端试图访问该数据库,因为每个人会试图打开一个连接(除第一次会得到一个错误)。

我创建涉及的赛道产卵的SSH过程和使用的所有通信一个可怕的解决方案。 血淋淋的细节是https://stackoverflow.com/a/27361295/558639 。 除了是真的缺憾,但这样会导致延迟每次进程启动,您是否在访问远程数据库的时间。

更新

因此,这里的出现很好地工作更好的方法:只需陷阱(和忽略) Errno::EADDRINUSE错误。 下面的代码:

require 'net/ssh/gateway'

class Mole

  TUNNEL_HOST = <redacted>
  TUNNEL_USER = <redacted>
  AWS_HOST = <redacted>
  TUNNEL_PORT_NUMBER = 3307

  attr_reader :tunnel_gateway, :tunnel_port

  # Call this to open an SSH tunnel from the current machine.  If the
  # the tunnel was already opened (e.g. by another process) , you'll
  # get a warning message
  def open_tunnel
    @tunnel_gateway = Net::SSH::Gateway.new(TUNNEL_HOST, TUNNEL_USER)
    begin
      @tunnel_port = @tunnel_gateway.open(AWS_HOST, 3306, TUNNEL_PORT_NUMBER)
    rescue Errno::EADDRINUSE => e
      $stderr.puts("Warning: #{e.class}: #{e.message}")
    end
  end

  # You won't normally call this, because the tunnel is a system wide
  # resource; you don't know when other processes want to release it.
  def close_tunnel
    r = @tunnel_gateway.close(@tunnel_port) if @tunnel_gateway
    @tunnel_gateway.shutdown!
    r
  end

end


文章来源: SSH from Heroku into remote server with Mysql Db