You have a service running on localhost:3000 and you want it reachable at yourapp.com with a real TLS certificate — no reverse proxy to configure, no ports to open, no certbot cron job. Setting up a custom domain for localhost (or any local or tunneled service) with Ngris is four steps: reserve a hostname, point your domain at the edge, let the edge issue the certificate, and run the agent. The Ngris agent makes an outbound connection to the Ngris edge, which terminates TLS and forwards requests back to your local port, so nothing is ever opened on your network.
Before you start, install the CLI and authenticate. The free plan gives you 5 endpoints and no credit card is required.
# macOS
brew install ngris
# Linux
curl -fsSL https://ngris.com/install.sh | sh
# Windows
winget install Ngris
# then authenticate
ngris auth --token <token>Reserve a hostname
Run ngris http 3000 with no flags and you get an ephemeral hostname: a public HTTPS URL that lives only while the agent is running. Restart the agent and the hostname changes. That is fine for a quick demo or a one-off webhook test, but it is the wrong foundation for a custom domain, because a CNAME has to point at something stable.
A reserved hostname stays yours across restarts. You claim it with --url, and from then on every session for that endpoint comes up on the same address. This is the target your custom domain will ultimately alias to, so reserve it first.
# ephemeral — changes every run
ngris http 3000
# reserved — stable across restarts
ngris http 3000 --url app.ngris.comReserve the hostname once and it will remain associated with your account. The rest of this guide assumes you have a reserved endpoint to attach your domain to.
Point your domain at Ngris
Now bring your own domain. In the dashboard, add the custom domain — for example yourapp.com — to your reserved endpoint. The dashboard will show you the CNAME target to create at your DNS provider.
Create one CNAME record pointing your domain at the Ngris edge:
# at your DNS provider
yourapp.com. CNAME cname.ngris.io.That single record is the entire DNS change. Requests to yourapp.com resolve to the Ngris edge, the edge matches the hostname to your endpoint, and traffic is forwarded down the agent's outbound connection to localhost:3000. There is nothing to configure on your side of the connection and nothing exposed on your network.
Automatic HTTPS
Once the CNAME resolves, Ngris issues the TLS certificate for your domain and terminates HTTPS at the edge. There is no certbot to run, no ACME challenge to wire up, and no renewal cron to babysit — the edge provisions the certificate and renews it before it expires. If you would rather not track that yourself, Iris, the AI built into Ngris, watches for things like certificate expiry and surfaces a nudge before it becomes a problem.
Because TLS terminates at the edge, your local service can keep speaking plain HTTP on port 3000. The public hostname is HTTPS end to end for anyone hitting yourapp.com, while the agent's tunnel back to your machine handles the transport.
Run it
With the domain added and the CNAME in place, start the agent against your custom domain:
# serve localhost:3000 at your own domain over HTTPS
ngris http 3000 --url yourapp.comThe agent connects out to the edge, the edge answers on https://yourapp.com, and requests land on your local port. Ship code, restart the process, redeploy — the domain and its certificate stay put.
What you get for free
Serving a custom domain through the Ngris edge is not just a DNS alias. The edge is a full gateway, so the same hostname gets more than a tunnel:
- HTTP/2 and HTTP/3 (QUIC) — the edge serves HTTP/1.1, HTTP/2, and HTTP/3 to clients regardless of what your local service speaks.
- A web application firewall — the Coraza-powered WAF attaches as a single traffic-policy rule, detect-by-default and then switch it to block.
- Rate limiting, mTLS, and JWT rules — part of the traffic-policy engine (23 rule types across ordered phases: WAF, JWT, mTLS, rate limits, transforms).
- Identity-aware access — put your domain behind SSO/OIDC (Google, GitHub, Okta) with unified RBAC, no VPN.
- Static egress IPs — a stable outbound IP that partners can allowlist.
- Traffic Inspector and Replay — a live Traffic Inspector filtered by host, path, status, or method, plus request Replay to re-send a captured request to any environment.
All of that binds to the same custom domain you just configured — you attach the rules you want as traffic policies and leave the rest off.
If you are new to exposing local services, start with exposing localhost to the internet for the basics of the agent and ephemeral hostnames, then come back here to put your own domain on top.
That is the whole procedure: reserve a hostname, add a CNAME to cname.ngris.io, and let the edge handle the certificate. Grab a token, run ngris http 3000 --url yourapp.com, and your local service is live on your own domain over HTTPS.