Introduction
osmRouter is a self-hosted, bring-your-own-domain reverse tunnel that exposes a local service at a public HTTPS URL on a domain you control.
Run a local server, point osmRouter at its port, and get a live https:// URL
that anyone on the internet can reach. Your machine dials out to the relay, so it
works behind NAT, firewalls, and CGNAT with no inbound ports and no router
configuration.
export OSM_TOKEN=osm_xxxxx
osmrouter http 8080
# -> https://quiet-river.osmrouter.com -> localhost:8080Get started
Quickstart
Authenticate, expose a local port, and pin a subdomain in under a minute.
Install the CLI
One command on macOS or Linux, or open a tunnel from code with the Node SDK.
HTTP tunnels
How tunnels route, what they carry, and how to pin a stable URL.
Traffic Inspector
See every request hit your tunnel — method, path, status, latency, size, IP.
The core idea: own your origin
Most tunnel services hand you a URL on their domain and put their brand on your traffic. osmRouter inverts that. You bring your own domain, your own dashboard, and (if you self-host) your own infrastructure. The public URLs your users see live on your hostname, not someone else's.
- Your domain. Tunnels resolve under your hostname (for example
my-app.yourcompany.com), not a shared third-party domain. - Your brand. No upstream vendor name, no interstitial warning page, no "powered by" banner in front of your service.
- Your infrastructure. The hosted plan runs on osmRouter, but the entire stack ships as a Docker Compose deployment you can run on a single box you control.
Who it is for
- Developers who need to share a dev server or receive webhooks from a third
party (Stripe, GitHub, Slack) on
localhost. - Teams who want an ngrok-style workflow but on their own domain and brand, with a traffic inspector and per-request visibility.
- Operators who want to self-host the whole platform on one server with no dependency on Cloudflare or other paid services.
- Anyone exposing on-device inference — an OpenAI-compatible server like Ollama, vLLM, or llama-server — to the public internet over a stable HTTPS endpoint.
What flows through a tunnel
HTTP tunnels carry far more than plain request/response. TLS is terminated at the edge with automatic Let's Encrypt certificates, so everything your visitors hit is real HTTPS.
- Plain HTTP and HTTPS.
- WebSockets and Server-Sent Events (SSE).
- Chunked and streaming responses.
- Long-running requests with no wall-clock timeout — a stream ends only when the visitor cancels it.
That last point is what makes osmRouter a good fit for streaming LLM responses and other long-lived connections, not just short web requests.
How it differs from ngrok
osmRouter covers the same expose-localhost workflow, but the ownership model is different in three ways that matter.
- Self-hosted. The full stack — relay, control-plane API, Postgres, Redis, and Caddy for TLS — runs as a Docker Compose deployment on infrastructure you control.
- Your domain, not theirs. Random URLs and pinned subdomains live under a wildcard domain you own. Custom hostnames are verified with a DNS TXT record.
- Your brand. No vendor branding and no warning interstitial in front of your service, on any plan.
osmRouter ships HTTP tunnels (osmrouter http) and raw TCP tunnels
(osmrouter tcp) — for databases, SSH, and game servers. HTTP tunnels can be
protected with Basic Auth. UDP is on the roadmap. The CLI runs on macOS, Linux,
and Windows.