ngrok is a tool that proxies traffic from a subdomain (like http://2fb551c6b2fd.ngrok.io) to a port on your localhost. I’ve been using it off and on for years. There’s a couple use cases I’ve used it for:
- Forward web traffic to a local next.js / webpack server, to show a website in progress without having to deploy it. This way I can send an ngrok link to a friend/coworker and they can see the latest.
- Forward api traffic from a device (ex. an iPhone if I’m working on an iOS app) to my local api server.
It’s been very useful, but recently I’ve switched to
ktunnel deploys a service on
kubernetes, which will proxy traffic to a local port of your choice. It’s more
work to set up than
ngrok, so it won’t be worth the hassle for a lot of
people, but there’s a few upsides to self-hosting.
The biggest benefit for me is that I can use my own domain, so instead of a random ngrok subdomain I’ll set it up on something like http://apiproxy.mbuffett.com. Additionally, there’s no connections limit, you’re only limited by the server you’re hosting your cluster on. Last but not least, it’s free if you have a cluster available, which I happened to have.
I’ll assume that you have a kubernetes cluster running. If you don’t, and want to get started with one,
you can start a cluster and connect to it with kubectl pretty quickly. I
recommend Digital Ocean, they have an easier setup than AWS/GKE. Once you’re at
the point where you can run
kubectl get all, and have an ingress controller
set up (I use
kong), then you’re
good to go.
First, you’ll need to install
ktunnel, check out the installation instructions
here for the latest. I built from source
but you can also get the latest binary. After that, you can start ktunnel like
ktunnel expose ktunnel-proxy <LOCAL_PORT>
This will create aservice on your cluster called
ktunnel-proxy, which will
take traffic on port 80 and forward it to your localhost on port
The next step is to expose the new service to the world. To do that, create an ingress that looks like this:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ktunnel-proxy spec: rules: - host: proxy.<YOUR_TLD> http: paths: - path: / backend: serviceName: ktunnel-proxy servicePort: 80
Of course, you’ll also have to set up DNS to get traffic from
YOUR_TLD to go to
your cluster. If you’re using Digital Ocean, you can point the A records to
a load balancer that points to your cluster.
So after this, when you go to
- DNS will resolve to your cluster IP
- The ingress controller will direct traffic to the
ktunnel-proxyservice will direct traffic to your
<LOCAL_PORT>on your localhost
Keep in mind that the termination process for ktunnel will try to delete the
service and deployment it created on startup. If you’ve lost internet connection
or something, it’s possible this doesn’t get run. If
ktunnel isn’t able to
start up, you may want to run
kubectl get services and see if there’s a stray
ktunnel service hanging around.
2020-08-01 17:19 +0000