Using Ngrok through Docker for local service development on Mac
Corporate policy restrictions got you down? Me too! I've struggled to find a reliable solution for local Slack, Github, or cloud development when Ngrok, the most commonly used tool for exposing services locally, is restricted by either a local execution policy or via OpenDNS (or similar). I've found the following Docker-based method to be a reliable workaround to those typical corporate or public network restrictions while still having the full functionality of Ngrok.
Prerequisites
Install Docker Desktop via Homebrew
brew install docker
Container
You could roll your own; however, there are already several popular options on Docker Hub to get you up and running immediately. I recommend wernight/ngrok, it's well-documented and easy to configure.
Update Started a fork to support some additional Ngrok arguments until they are merged in sirkirby/ngrok
docker pull wernight/ngrok:latest
Starting your tunnel
On the host, I'm exposing a local rest API on port: 5000
, which Ngrok will expose on the internet. I also want to access the Ngrok request inspector running inside the container on port: 4040
.
docker run --rm -p 4040:4040 -p 5000:5000 -e NGROK_PORT="host.docker.internal:5000" \
-e NGROK_AUTH="{your_account_key}" -e NGROK_SUBDOMAIN=mycname wernight/ngrok
NOTES AND CONSIDERATIONS
- On Mac, the host address changes, so you need to utilize the reserved DNS name
host.docker.internal
in your port binding. See https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support for more info. - The
NGROK_AUTH
andNGROK_SUBDOMAIN
env args are optional and are primarily used with a paid account. Free accounts will generate a random CNAME each time you initialize a tunnel. - You may run into a port conflict with your service when using explicit port binding. Start your service before the docker container, which should mitigate the issue.
- Rather than binding the ports individually, you can use the host network directly via the
--net=host
flag. When used in combination with-p
, the port mappings are ignored. The only limitation I found with this solution was the inability to connect to the ngrok HTTP inspector from the browser.
Conclusion
Pretty simple! Slack commands (or your use case) are now flowing to your local service; no policy exceptions are required.