Publicly exposing a local service to nearby and far away consumer on the internet using ngrok image

Publicly exposing a local service to nearby and far away consumer on the internet using ngrok

Sometimes I run into a tool or service that brings a large smile on my face. Today that happened to me as I was reading a blog article on chatbots. It mentioned a service -ngrok – that was used during the testing face of that chatbot. The chatbot needs to be accessible to Facebook – messages sent from a Facebook Messenger client on some mobile device to the Facebook Messenger server are to be forwarded and handled by the chatbot. Instead of deploying the locally developed chatbot to a public cloud, over and over again, the approach taken was the use of ngrok – a service that allows a client to make its local services (REST APIs on Node.js, Web site on Apache HTTP or NGINX, web application on PHP, Python, Tomcat or web service on a local service bus) accessible through a secure public URL.

This means that – regardless of firewalls, NAT, router configuration etc. – anyone can make services running locally and accessible over HTTP(S) or TCP on localhost:someport also accessible remote clients. For many development and testing scenarios, that has tremendous benefits. I can remember many situations where those benefits would have been much appreciated. (see for example how Luc Bors and I struggled for our demo in Budapest in 2015 – saving the day using a personal hotspot on a mobile phone to allow to laptops close together to connect).

Here a simple challenge: two developers, one developing a REST API that is running locally, the other working on a mobile app that needs access to that local REST API.

image

Using ngrok this would be turned into:

image

After reading about ngrok, I had to try it out. To see if it lives up to the promise. Here is my very quick report. Bottom line: it does [live up to the promise].

Note: I have done my exploration on a Windows 7 machine, sitting on the kitchen table at home, wirelessly connected to the home network that has a router with no ports specifically configured to allow incoming traffic (I never got round to that).

 

1. Go to the ngrok website: https://ngrok.com/ . Sign up – for example using a GitHub account (which is what I did)

2. Download ngrok for your platform

image

 

SNAGHTML18d25a1

Install locally – which basically means: extract ngrok from the archive.

3. Install the authtoken you are presented with after signing up

SNAGHTML18f20e0

The authtoken is saved in a local yaml-file. You can edit this file to add the configurations for tunnel that you want ngrok to open up – see documentation.

4. Run ngrok for its first default tunnel:

ngrok http 80

 

After a little while, this status overview is shown:

image

This indicates that a URL on the ngrok public server has been set aside for my client. Any request sent to that url is routed to the ngrok client running locally and forwarded to localhost:80.

I can easily try out if this works, by simply accessing that URL from a browser – either on my own laptop or on any other computer anywhere in the world connected to the internet. The response I get:

image

is completely correct. I currently do not have any service running locally listening to HTTP requests on port 80.

Note that ngrok provides a local monitoring application that is exposed on port 4040 by default:

image

It shows the publicly exposed URLs for my client. It also provides an overview of all requests handled by ngrok:

image

5. The eating of the pudding: Run a real local server (Node.js application) and access it from my mobile phone

I have create a very simple node.js application (https://github.com/lucasjellema/sig-nodejs-amis-2016/tree/master/part2-http – the http-2.js application). I run it locally, listening on port 3000:

image

My objective is now to have ngrok make it possible for external consumers to access this very simple application.

I restart the ngrok client:

ngrok http 127.0.0.1:3000

The status information displayed:

SNAGHTML199f10a

I have been assigned a public URL (note: under the free plan, every time the ngrok client is restarted, a new URL is assigned).

I can now access this public URL on my laptop:

image

This is promising, but not yet convincing proof.

Now I access the same URL on a mobile device – let’s pretend it is located three time zones from my laptop:

IMG_6671

Now I am convinced. In a few very simple steps and without incurring any costs, I have accessed a Node.js application running on my laptop from a random device over the public internet.

This opens up interesting possibilities – and will prevent a lot of grief in the road ahead!

 

Additionally

Ngrok has several price plans. I have used the free plan – which assigns new random urls every time the client is restarted and does not allow more than 40 connections per minute (I am not sure if connections and requests are the same thing?). Still, probably enough for many testing scenarios. The basic plan ($5/month) allows three reserved domains (fixed URLs) and 60 connections/minute. Then there are pro and business plans – check out ngrok pricing for details.