Self hosted ngrok server in Docker Lajos Papp 09 October 2014

Ngrok is used for introspected tunnels to localhost. In integration testing situations is really common that you want to bind some webhooks to localhost. For example you want AWS SNS deliver messages to your service, but is not reachable publicly, as it runs only on localhost.

So its really 2 in 1: local tunnel and introspection. Sometimes you just want to use its introspection feature, to get insight about how a specific API works. It’s like a local runscope.

While you can always use the free hosted version: ngrok, there are reasons to roll you own:

  • Sometimes the free hosted version has availability issues,when it gets heavy traffic
  • Yo don’t want your messages/calls go through a public free service, for security concerns
  • You just want to use its introspection feature, and want to avoid the extra network round trip to ngrok.com and back.

There is documentation about self hosting ngrok But it include steps, like:

  • create an SSL certificate
  • build server/client binaries using the cert above
  • configure, and install it on your server

How about using a single click version of this? Easy: we have already containerized this process and made it available in the official Docker repository.

Running

To launch the ngrok daemon, you just have to start the sequenceiq/ngrokd Docker image:

1
2
3
4
5
6
7
8
docker run -d --name ngrokd \
  -p 4480:4480 \
  -p 4444:4444 \
  -p 4443:4443 \
  sequenceiq/ngrokd \
    -httpAddr=:4480 \
    -httpsAddr=:4444 \
    -domain=ngrok.mydomain.com

It will expose 3 ports:

  • 4444: that is the so called control port, ngrok clients connect there
  • 4480/4443: this to port is used for the tunneled http/https connections
  • domain: this is the domain name, clients need to use to connect to the server, and the ngrok server will assign <SUBDOMAIN>.ngrok.mydomain.com addresses to each tunnel.

Install the custom ngrok client

You remember we have a custom ngrok daemon inside the Docker image. Based on the self hosting documentation

Since the client and server executables are paired, you won’t be able to use any other ngrok to connect to this ngrokd, and vice versa.

So we need the paired ngrok client

OSX

If you use brew:

1
brew cask install https://raw.githubusercontent.com/sequenceiq/docker-ngrokd/master/ngrok.rb

otherwise:

1
2
curl -o /usr/local/bin/ngrok https://s3-eu-west-1.amazonaws.com/sequenceiq/ngrok_darwin
chmod +x /usr/local/bin/ngrok

Linux

1
2
curl -o /usr/local/bin/ngrok https://s3-eu-west-1.amazonaws.com/sequenceiq/ngrok_linux
chmod +x /usr/local/bin/ngrok

Please make sure you check the ngrok version:

You should see the 1.7.2 on client side:

1
2
3
> ngrok version

1.7.2

Client configuration

1
2
3
4
cat > ~/.ngrok <<EOF
server_addr: ngrok.mydomain.com:4443
trust_host_root_certs: false
EOF

Hostname workaround

If you want to run ngrokd internally just use a new entry in /etc/hosts

1
<NGROKD_IP> ngrok.mydomain.com subdomain1.mydomain.com subdomain2.mydomain.com

If you want a proper subdomain you need an A record such as: *.ngrok.mydomain.com 54.72.21.93

Usage

Starting ngrok is business as usual, just use ngrok <port>. Pretty much that’s it, you have a self-hosted ngrok server in Docker. Then you can introspect the tunnel on http://127.0.0.0:4444

Sample use case

To fully understand how Docker works, sometimes it’s useful to see how the Docker client communicates with the Docker server. You can just use ngrok to introspect the Docker API.

1
ngrok -subdomain=docker 127.0.0.1:2375

then if you want to record API calls you have to configure

1
alias docker='docker --host=tcp://docker.ngrok.mydomain.com:4480'

For updates follow us on LinkedIn, Twitter or Facebook.

Comments

Recent Posts