Running Rails on Unicorn via Pow, is it possible to know what port Unicorn is running on?

887 views Asked by At

In my Ruby on Rails dev environment, I am starting Rails and Unicorn via Foreman in the typical way:

(Procfile:)

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

I am also running Pow. But not as a webserver. I'm just using Pow to direct http requests from mydomain.dev (port 80) to the port Unicorn is listening on.

You can do this by creating a pow file (mydomain.dev) containing the port number Unicorn is running on.

Given this setup, is it possible in my rails code to know what the port I started Unicorn on?

I'm only wanting to know this in my dev environment, it's not a production issue.

In my Rails code, I've tried a few different things, but none of them work:

  • Unicorn::Configurator::RACKUP[:port] - returned nothing
  • Rails::Server.new.options[:Port] - doesn't exist in Rails 4
  • Rack::Server.new.options[:Port] - returns default rack port (9292) not the one configured for this rack instance.

    Is there a way to get the current rack instance from rails?

  • request.port - returns 80, which is the port that Pow is listening on. Pow is routing http traffic to Unicorn, which is on a different port.

None of these give me the port that Unicorn is running on.

Any ideas?

EDIT If you're wondering why I want to know this, it's because in my dev environment, I'm trying to dynamically create configuration files for Pow, so I can route http requests to Unicorn on the correct port.

4

There are 4 answers

3
adamliesko On

If you're responding to a request in a controller or view, use the request object - this should work, although you say it does not:

request.port

If you're in an initialiser :

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

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

4
Glenn Gillen On

You should just be able to access it via ENV['PORT'], given it's value has been set to the $PORT environment variable.

0
hoffmanc On

Probably a bad idea, but whatever:

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

I've sort of found a way to do this.

  1. Create separate config files for Unicorn. unicorn.development.rb and unicorn.test.rb
  2. Install the dotenv-rails gem
  3. Inside my unicorn config files, do something like this: # 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. In my .env.development and .env.testing environment files, set the UNICORN_PORT environment variable

  5. Make sure you use the correct Unicorn config file to start the app. This can be done by using separate Procfiles for dev and testing.

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

This appears to mostly work, but is not without it's issues...