'How do I dynamically add my Ngrok tunnel to config.hosts in Rails 6?

I'm trying to whitelist my ngrok tunnel hostname in config.hosts but it changes every time I start Ngrok. Is there a way to get the public url of my Ngrok tunnel so that I don't have to use hosts.clear?



Solution 1:[1]

Simply configure config/environments/development.rb like so:

Rails.application.configure do

  ...

  config.hosts << '.ngrok.io'
end

This will allow requests from any subdomain of ngrok.io.

Solution 2:[2]

Ngrok has a built in JSON API that can be found on localhost:4040/api/tunnels.

# lib/ngrok_client.rb
module NgrokClient
  def self.tunnels
    response = Net::HTTP.get(URI('http://localhost:4040/api/tunnels'))
    begin
      JSON.parse(response).dig("tunnels")
    rescue JSON::ParserError => e
      Rails.logger.error %q{
        Failed to parse reponse from Ngroks internal API. Are you sure its running?
      }
    end
  end
  def self.public_urls
    tunnels.select do |h|
      # TODO - don't hardcode the host name
      h.dig("config", "addr") == "http://localhost:3000"
    end.map { |h| URI(h["public_url"]).hostname }.uniq
  end
end
# config/environments/development.rb
Rails.application.configure do
  # ...
  require 'ngrok_client'
  config.hosts += NgrokClient.public_urls
end

There is also the ngrok-tunnel gem that can be used to start ngrok from the middleware layer as a less hacky soultion.

Solution 3:[3]

https://stackoverflow.com/a/70361487/14001685 didn't work for me (Rails 6) but regex did.

config.hosts << %r{.+\.ngrok.io$}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jerome Dalbert
Solution 2
Solution 3 nerzie