Skip to content

Instantly share code, notes, and snippets.

@tasandberg
Created April 23, 2021 18:43
Show Gist options
  • Save tasandberg/c02be39870ff5dc95a179496968e1238 to your computer and use it in GitHub Desktop.
Save tasandberg/c02be39870ff5dc95a179496968e1238 to your computer and use it in GitHub Desktop.
Start rails using dynamic ngrok host name
  1. Get ngrok https://ngrok.com/download
  2. Start ngrok ngrok http 3000
  3. In a separate terminal, in your rails directory:
  • copy ngrok-host script above to bin/ directory (drop the .rb, its just there for gist syntax highlighting.
  • make the file executable: chmod +x bin/ngrok-host
  • run: bin/ngrok-host

The script queries the local ngrok instance for available tunnels, grabs the https host name, and starts rails with that hostname configured for url helpers and the like.

But why?

Ngrok is a really useful tool for allowing access to a development server over a public URL with TLS encryption. I specifically needed this for testing an Android react-native client against a rails API.

The problem: starting and stopping Ngrok on a free account rotates and I got tired of copy-pasting the ever-changing hostnames into my rails config when I needed to restart.

# frozen_string_literal: true
# Update config/environments/development.rb as follows:
Rails.application.configure do
...
routes.default_url_options[:host] = ENV.fetch('HOSTNAME', 'localhost:3000')
end
#!/usr/bin/env ruby
# frozen_string_literal: true
# this lives in bin/ngrok-host without the ".rb" extension
require 'httparty'
# Start rails server using temporary ngrok url for host names for urls (testing deep linking)
ATTEMPT_LIMIT = 5
attempts = 0
ngrok_host = nil
while ngrok_host.nil? && attempts < ATTEMPT_LIMIT
begin
response = HTTParty.get('http://127.0.0.1:4040/api/tunnels')
https_tunnel = response.parsed_response['tunnels'].find { |t| t['proto'] == 'https' }
ngrok_host = https_tunnel['public_url']
rescue StandardError => e
p e
puts "Host not ready, retrying... #{ATTEMPT_LIMIT - attempts} tries left"
attempts += 1
sleep 1
end
end
if ngrok_host
puts "NGROK Host Found, starting rails"
hostname = URI.parse(ngrok_host).host
exec("HOSTNAME=#{hostname} bundle exec rails s")
else
puts 'Unable to find ngrok host'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment