【问题标题】:Running Rails on Unicorn via Pow, is it possible to know what port Unicorn is running on?通过 Pow 在 Unicorn 上运行 Rails,是否有可能知道 Unicorn 在哪个端口上运行?
【发布时间】:2015-07-29 07:41:28
【问题描述】:

在我的 Ruby on Rails 开发环境中,我通过 Foreman 以典型的方式启动 Rails 和 Unicorn:

(过程文件:)

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

我也在运行 Pow。但不是作为网络服务器。我只是使用 Pow 将来自 mydomain.dev(端口 80)的 http 请求定向到 Unicorn 正在侦听的端口。

您可以通过创建一个包含 Unicorn 正在运行的端口号的 pow 文件 (mydomain.dev) 来做到这一点。

鉴于此设置,是否可以在我的 rails 代码中知道我启动 Unicorn 的端口是什么?

我只想在我的开发环境中知道这一点,这不是生产问题。

在我的 Rails 代码中,我尝试了一些不同的方法,但都没有奏效:

  • Unicorn::Configurator::RACKUP[:port] - 没有返回任何内容
  • Rails::Server.new.options[:Port] - Rails 4 中不存在
  • Rack::Server.new.options[:Port] - 返回默认机架端口 (9292),而不是为此机架实例配置的端口。

    有没有办法从 rails 获取当前机架实例?

  • request.port - 返回 80,这是 Pow 正在侦听的端口。 Pow 正在将 http 流量路由到位于不同端口上的 Unicorn。

这些都没有给我 Unicorn 正在运行的端口。

有什么想法吗?

编辑如果你想知道为什么我想知道这个,那是因为在我的开发环境中,我正在尝试为 Pow 动态创建配置文件,所以我可以将 http 请求路由到 Unicorn在正确的端口上。

【问题讨论】:

    标签: ruby-on-rails rack unicorn foreman rack-pow


    【解决方案1】:

    如果您在控制器或视图中响应请求,请使用请求对象 - 这应该可以,尽管您说它没有:

    request.port
    

    如果你在初始化器中:

    Rails::Server.new.options[:Port]
    

    How to find the local port a rails instance is running on?

    【讨论】:

    • request.port 返回 80。我想那是因为我正在使用 Pow,而 Pow 正在侦听 80,然后将流量转发到另一个端口上的 Unicorn。
    • Rails::Server.new.options[:Port]Rack::Server.new.options[:Port] 相同,这是在较新版本的 Rails 中使用的。我不知道这只适用于初始化程序,所以我现在就试试。
    • 我认为在哪里调用 Rack::Server.new.options[:Port] 并不重要,它也可以在初始化程序之外工作。但这将返回机架服务器的默认端口,即 9292。它不会返回具有配置端口的实际机架服务器实例。
    【解决方案2】:

    您应该只能通过ENV['PORT'] 访问它,因为它的值已设置为$PORT 环境变量。

    【讨论】:

    • 不,这行不通。因为 $PORT 是由 Foreman 在 .foreman 文件中设置的。我曾经使用它 - 但是它不允许我在开发和测试环境中使用不同的 $PORT 值。
    • 问题是:“要知道我启动 Unicorn 的端口是什么”,而您说“$PORT 正在由 Foreman 设置”。鉴于 foreman 正在启动 Unicorn,为什么不是这正是您需要的?您可以通过在命令行上为foreman 提供不同的值来拥有不同的端口:$ foreman start --port 2000。我从未使用foreman 来运行我的测试,标准的 ruby​​ 工具 + bundler通常会为我提供所需的一切,而无需流程管理器的提取开销。
    • 好的,我不知道我可以在命令行上将端口传递给 Foreman。我想如果可能的话我想避免这种情况。
    • 我认为我通过工头运行测试服务器的想法无论如何都不是一个好主意。我主要是尝试通过 selenium 运行功能测试。我不喜欢 Capybara 启动的测试服务器的工作方式,并希望它使用与开发环境相同的独角兽设置,但只是在不同的端口上。问题是我的应用程序为 Pow 动态创建虚拟目录文件,它需要知道正确的端口。无论如何...我现在有点工作。感谢您的 cmets。
    【解决方案3】:

    我已经找到了一种方法来做到这一点。

    1. 为 Unicorn 创建单独的配置文件。 unicorn.development.rbunicorn.test.rb
    2. 安装dotenv-rails gem
    3. 在我的独角兽配置文件​​中,执行以下操作: # unicorn.development.rb:

      require "dotenv"
      Dotenv.load(
        "./.env.local",
        "./.env.development",
        "./.env"
      )
      
      if ENV['UNICORN_PORT'].nil?
        throw 'UNICORN_PORT not set in environment!'
      end
      
      worker_processes 3
      timeout 30
      preload_app true
      
      listen ENV['UNICORN_PORT'], backlog: 64
      
      ... rest of unicorn config...
      
      
      
      
      # unicorn.testing.rb:
      
      require "dotenv"
      Dotenv.load(
        "./.env.local",
        "./.env.testing",
        "./.env"
      )
      
      if ENV['UNICORN_PORT'].nil?
        throw 'UNICORN_PORT not set in environment!'
      end
      
      worker_processes 3
      timeout 30
      preload_app true
      
      listen ENV['UNICORN_PORT'], backlog: 64
      
      ... rest of unicorn config...
      
    4. 在我的.env.development.env.testing 环境文件中,设置UNICORN_PORT 环境变量

    5. 确保您使用正确的 Unicorn 配置文件来启动应用程序。这可以通过使用单独的 Procfile 进行开发和测试来完成。

      # Procfile.dev
      web: bundle exec unicorn -c ./config/unicorn.development.rb
      
      # Procfile.testing
      web: bundle exec unicorn -c ./config/unicorn.testing.rb
      

    这似乎大部分都有效,但并非没有问题......

    【讨论】:

      【解决方案4】:

      可能是个坏主意,但无论如何:

      uport = `netstat -n --listening --tcp -p | grep unicorn | sed 's/.*:\([0-9]*\) .*/\1/'`
      

      【讨论】:

        猜你喜欢
        • 2012-06-01
        • 2022-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-05
        • 1970-01-01
        • 1970-01-01
        • 2022-11-20
        相关资源
        最近更新 更多