A quick addendum to my previous ngrok post. If you are not using subdomains, it can be useful for your app to know what ngrok’s dynamically generated URL is. The simplest way to do that is to set an environmental variable. I like APP_URL, but you can use whatever.

Just add:

1
ENV['APP_URL'] = Ngrok::Tunnel.ngrok_url_https

to config/puma.rb after the ngrok tunnel is started. The entire code becomes:

1
2
3
4
5
6
7
8
9
if Rails.env.development?
  require 'ngrok/tunnel'
  options = {   addr: ENV.fetch("PORT") { 3000 },
                config: File.join(ENV['HOME'],'.ngrok2','ngrok.yml')
            }
  options[:subdomain] = ENV['NGROK_SUBDOMAIN'] if ENV['NGROK_SUBDOMAIN']
  puts "[NGROK] tunneling at " + Ngrok::Tunnel.start(options)
  ENV['APP_URL'] = Ngrok::Tunnel.ngrok_url_https
end

(I’m using the HTTPS URL, but you can swap it out for Ngrok::Tunnel.ngrok_url.)

With that, you can do things like automatically set callback URLs:

1
2
<a href="https://login.example.com/oauth2/authorize?redirect_uri=<%=
ENV['APP_URL'] %>/oauth">Login</a>

There is an alternative to approach, using request.base_url as in:

1
<a href="https://login.example.com/oauth2/authorize?redirect_uri=<%= request.base_url %>/oauth">Login</a>

This works fine if you are handling a web request in a controller/view, but isn’t available in models/libraries (unless you pass it in).

Finally, the above is needed to handle a hostname that isn’t static. If it is, you can just set:

1
Rails.application.routes.default_url_options[:host] = staging.example.com'

in config/environments/{development,production}.rb.

Comments