Tunnel your localhost to a custom domain
Random subdomains like a3f8k2x9.ttn.uz are fine for scratch work. The moment you hand a link to a client, a reviewer, or a webhook config that lives longer than the session, you want your own domain. staging.myapp.com pointing at your laptop. webhooks.myapp.com wired up to Stripe.
Here's how that works on TezTun and what to know before you wire it up.
The mental model
When someone hits myapp.com:
- Their browser asks DNS for the IP.
- DNS answers with TezTun's server IP (because you added a CNAME).
- Their browser connects to our server and does a TLS handshake.
- Our server looks at the
Hostheader, seesmyapp.com, finds the tunnel bound to that domain, and pipes the traffic down the WebSocket to your laptop. - Your local service responds. The response flows back the same way.
The parts you set up: the DNS record and a one-time verification. The parts we handle: the TLS certificate (via Let's Encrypt), the Host-based routing, and the tunnel.
Step-by-step
1. Add the domain in the dashboard
At app.teztun.uz, open Domains → Custom Domains → Add. Enter myapp.com (or a subdomain like staging.myapp.com). You'll see the exact DNS record to add.
2. Add the DNS record
At your DNS provider (Cloudflare, Namecheap, Route 53, whatever), add:
Type: CNAME
Name: myapp.com (or staging)
Value: ttn.uzApex domains (no subdomain): many providers don't allow CNAMEs at the root. Cloudflare "CNAME flattening" handles it. On other providers, use an A record pointing to our server IP instead — the UI will show the correct value.
On Cloudflare: set the CNAME to DNS only (grey cloud) for the initial verification. Switch it to proxied (orange cloud) afterwards if you want; either works.
3. Verify
Back in the dashboard, click Verify. We resolve the domain and check it points at us. Propagation is usually instant but can take a few minutes on slow DNS providers.
4. Start a tunnel
Run the CLI. When you pick a domain for this tunnel, your custom domain appears in the list alongside your subdomains. Pick it, and you're live:
$ teztun http 3000 --domain myapp.com --basic-auth admin:secret
Tunnel is active!
Subdomain: https://myapp.ttn.uz → localhost:3000
Custom: https://myapp.com → localhost:3000 (basic auth on)The --basic-auth flag is optional but handy here: a custom domain makes staging look real, and real-looking staging gets crawled by bots. A one-line user:password enforces a 401 at our edge before a single byte reaches your laptop. Drop it if the site should be public.
HTTPS is automatic
The first request to myapp.com triggers a Let's Encrypt certificate issue. It takes about two seconds. After that the cert is cached and renewed automatically. You don't manage keys, run certbot, or think about it.
Limits & edge cases
- Max access. Custom domains are included with Max, which new accounts receive automatically. TezTun is free through December 31, 2027.
- 10 domains per account. Enough for staging, production demo, a couple of side projects.
- One tunnel at a time per domain. Starting a new tunnel on a domain replaces the binding.
- Domain abuse. We verify domain ownership via DNS before issuing certs. Pointing a CNAME at us for a domain you don't own won't get a cert.
- When the tunnel is down. Visitors see a connection error, not a stale page. This is a feature — no caching surprises.
What it's good for
- Staging environments running off your laptop for short-lived demos.
- Webhook receivers that need a stable, branded URL.
- Sharing a work-in-progress with a client on your company domain, not a third-party one.
- IoT and hardware prototypes on a custom domain without hosting a server.
What it's not for
- Production traffic that has to be up when your laptop isn't. Put that on a VPS.
- Anything that absolutely cannot route through our servers. Use a different, self-hosted tunneling tool instead; TezTun is a hosted service.