How to Expose localhost to the Internet (HTTPS in One Command)

A practical guide to exposing a local port to the internet: how tunnels work, a one-command HTTPS setup with inrok, the SSH fallback, and the security basics to get right.

You're running something on localhost:3000 and someone who isn't you needs to reach it: a webhook from Stripe or GitHub, a client who wants to click through a work-in-progress, your phone testing a mobile layout, a friend joining your game server. localhost only exists on your machine — here's how to give it a real URL, safely.

Why you can't just share your IP

Two things stand between your laptop and the internet:

A tunnel sidesteps both: a small client on your machine opens an outbound connection to a relay server with a real public address, and visitors reach you back through that connection. Outbound connections are allowed pretty much everywhere, so this works behind NAT, CGNAT, hotel Wi-Fi, and office networks.

The one-command version

With inrok (our service — free while in beta, no card needed):

curl -fsSL https://inrok.in/install.sh | bash
inrok login
inrok http 3000

That prints a public HTTPS URL pointed at your local port 3000. TLS is handled at the edge — your visitor sees a padlock, you change nothing in your app.

Want a URL that survives restarts? Name it:

inrok http 3000 --name demo
# → https://demo.share.inrok.in — yours across reboots and network drops

Raw TCP and UDP endpoints are coming soon. The free beta includes 100 GiB of bandwidth a month and 3 simultaneous tunnels; on Windows, use install.ps1 instead.

The zero-install version

If you can't (or don't want to) install anything, SSH can do it alone:

ssh -R 80:localhost:3000 localhost.run

This prints a temporary public URL proxied over SSH. The URL changes every session and bandwidth is best-effort, but for a five-minute demo it's unbeatable. Our comparison of tunneling options covers more alternatives, including self-hosted ones.

Security basics — read before you share

A tunnel makes your service public. Five rules of thumb:

  1. Expose the app, not the box. Tunnel a single port to the specific service you mean to share — never a remote-desktop or SSH port "just to have it".
  2. Auth must live in the app. If the dashboard you're sharing has no login, anyone with the URL has full access. Add auth (or at least basic auth in a reverse proxy) before tunneling.
  3. Treat the URL as semi-secret. Unguessable URLs are not access control, but don't post one in a public channel unless you mean the whole world.
  4. Watch what webhooks can do. A webhook endpoint that mutates state should verify signatures (Stripe, GitHub, and friends all sign their payloads).
  5. Tear it down when you're done. inrok stop (or Ctrl-C) closes the tunnel. A demo tunnel left up for three weeks is an attack surface, not a convenience.

When a tunnel is the wrong tool

If you're deploying something for real users 24/7, a proper host (a VPS, a PaaS, or your homelab with real DNS) is the right home for it — tunnels shine for development, demos, webhooks, and personal self-hosted services. For that last category — say, streaming your Jellyfin library from home — a persistent tunnel is arguably the best tool, CGNAT or not.

Ready to try? Create a free account — the whole flow above takes about two minutes.