Every developer tool for getting code onto the internet falls into one of two buckets. In one bucket are the tools that expose something you're already running — ngrok, Cloudflare Tunnel, localtunnel — they open a public URL to your laptop or your Kubernetes service. In the other bucket are the tools that deploy something you built — Netlify, Vercel, Cloudflare Pages — they take a folder or a repo and host it for you.
You almost always need both, at different moments, and today that means two vendors, two dashboards, two bills, and two completely separate security stories. Ngris is the one tool that does both — behind one policy edge, with an AI that writes your rules. That's not a slogan; it's the actual shape of the product, and this post walks through how it fits together.
The two-buckets problem
Think about a normal week. On Monday you're building a feature and you need a teammate to see it, or a webhook provider to reach your laptop — that's an expose problem, so you reach for a tunnel. On Thursday the marketing site or the SPA is ready and needs a real URL people can bookmark — that's a deploy problem, so you reach for a static host. Different tools, different mental models, and neither one knows the other exists.
The seam between those two buckets is where all the annoying work lives. Your tunnel has whatever auth ngrok gives you; your deployed site has whatever auth Netlify gives you; if you want a WAF or a rate limit or an IP allowlist you're bolting on a third product for each. The security posture of "the thing on my laptop" and "the thing I shipped" are configured in different places, with different vocabularies, by different tools that will never agree.
Ngris does both — behind one edge
Here's the "wait, it's all one tool?" part. Ngris is a two-sided edge platform. You can expose a private HTTP, TCP, or UDP service through the edge (the tunnel — ngrok, but policy-first), or you can deploy a static site or SPA to that same edge (Vercel/Netlify-style hosting — zip or git push → live URL). Two doors into the same building.
Exposing something you're running is one command — the full walkthrough is in expose localhost to the internet, but it's just this:
# Install the agent
curl -fsSL https://ngris.com/install.sh | sh
# Expose the app running on port 3000 — public HTTPS URL, no port forwarding
ngris http 3000
Deploying something you built is one call (or a git push, or a folder drop):
# Deploy a static site / SPA to the edge
curl -X POST https://api.ngris.com/v1/applications/quick-deploy \
-H "X-API-KEY: $NGRIS_API_KEY" \
-F "name=my-site" -F "file=@dist.zip" -F "wait=true"
That single call creates the app, uploads it, provisions the public endpoint, and returns the live URL. Or connect a GitHub/GitLab repo and every push builds and ships automatically — Ngris detects the framework (Vite, Next.js, Astro, SvelteKit, and more), builds it in a locked-down sandbox, and serves the result from the edge with a shareable preview URL for every deploy.
What Deploy builds: it builds and hosts front-end framework and JAMstack apps. Ngris runs your npm/yarn/pnpm install and build in a sandboxed job and serves the output on the edge — React (Create React App), Vite, Vue, Svelte/SvelteKit, Angular, Astro, Gatsby, Next.js (static export), Nuxt (generate) and Hugo are auto-detected (and overridable), plus prebuilt static served as-is.
One honest boundary up front: Ngris builds and hosts your front end and runs your backend — push a Go, Node, or Python service (auto-detected) or any Dockerfile (any language or framework, a Next.js server included) and Ngris builds it in a sandboxed job and runs it on the edge behind the same policy engine. The one thing it does not run is per-request serverless / edge functions (there is no FaaS runtime) — you deploy a long-running backend instead. If your architecture is FaaS-first, that's a genuine gap today.
A full-stack app can get a managed database
A backend usually needs a database, so a full-stack app on Ngris can add one from the Application detail page — a managed, MySQL-compatible database (MariaDB). It's the one engine on offer: not Postgres, not Redis, not Mongo. Click Add database and Ngris provisions it and wires it into your app; there's nothing to stand up or operate yourself.
The design decision worth calling out is per-app isolation. Each app gets its own schema and a dedicated least-privilege user whose grants are scoped to that one schema (SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX — and nothing global), on a hardened, in-cluster mariadb-apps server. Provisioning runs in a locked-down one-shot job (non-root, all Linux capabilities dropped, read-only root filesystem, seccomp) and the admin credential that creates schemas never touches your app or the long-running worker. Your app can't reach another app's data because its user simply isn't granted it.
The connection is injected into your app's environment — there are no secrets to copy. When the database is ready, Ngris sets DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD, and a ready-to-use DATABASE_URL (a mysql:// DSN) as env vars, encrypts the password at rest, and redeploys your app so it picks them up. Your code just reads DATABASE_URL from the environment.
Two honest bounds: the managed database is a paid-plan capability (it's off on the free tier), and it applies to the deploy side — a full-stack app that Ngris runs in-cluster — not to tunnels.
The same policy engine, whichever door you came in
This is the part that makes it one product instead of two features glued together. A deployed app and a tunneled service are both, underneath, the same thing: an Ngris endpoint. And every endpoint — no matter which bucket it came from — runs behind the same per-endpoint policy engine.
That engine has 17+ traffic-policy rule types across ordered phases: rate limits, CIDR and geo restrictions, JWT and API-key auth, a Coraza-powered WAF, JA3 bot management, CORS, request/response rewrites, and more. Put a WAF in front of your deployed marketing site the exact same way you put one in front of your tunneled staging API. Require Google login on a tunnel and on a static internal dashboard with the same auth flow. Rate-limit both. Inspect and replay the live traffic hitting either one in the same dashboard.
| You want to… | Expose (tunnel) | Deploy (static/SPA) |
|---|---|---|
| Get a public HTTPS URL | ngris http 3000 | zip / git push → live URL |
| Attach a WAF | traffic-policy rule | the same traffic-policy rule |
| Require login (OAuth/SSO) | per-endpoint auth | the same per-endpoint auth |
| Rate-limit or IP-allowlist | traffic-policy rule | the same traffic-policy rule |
| Custom domain + automatic TLS | ||
| Inspect & replay live traffic |
ngrok tunnels and stops there. Vercel and Netlify deploy and stop there. Nobody unifies expose + deploy behind a single policy edge — so the security layer, the observability, and the bill are all one thing instead of a pile of separate vendors you have to keep in sync.
Iris writes the rules
The policy engine is powerful, which normally means "read the docs and learn the rule syntax." Ngris ships an AI assistant — Iris — that writes those rules from plain English. Describe the behavior you want and Iris drafts the traffic-policy rule — the right phase, the right match — for you to review:
# In the Iris chat, on any endpoint (tunnel or deployed app):
"Block requests from outside the EU and rate-limit
/login to 10 attempts per minute per IP."
Iris turns that into a geo-restriction plus a rate-limit rule and shows you a confirmation card with a blast-radius dry-run before anything is applied. It generates firewall rules, rate limits, full traffic policies, routing rules, error templates, and metric alerts. Because a deployed app and a tunnel are the same kind of endpoint, the same Iris flow secures both.
Two honest caveats so you know exactly what Iris is: every write beyond a firewall rule needs your explicit approval — Iris drafts and previews, you confirm. There's an opt-in firewall-only autonomy mode that can apply a reversible block after a passing dry-run and auto-revert if it hurts real traffic, but that autonomy is scoped to firewall rules and nothing else. On the reading side Iris does more: it answers questions about your account (endpoints, members and roles, plan entitlements and quotas, verification) by reading the live API, and it searches your HTTP traffic logs from a plain-English query — all under your own permissions.
Hosted, not self-hosted
Ngris is a hosted SaaS platform. You don't stand up a server, run a control plane, or operate the edge — you install a small agent (for tunnels) or push your build (for deploys), and the managed edge does the rest across multiple regions with automatic TLS. Pricing is simple and self-serve: $0 to get started with no credit card, $8/mo for the Team plan, and $25/mo for Enterprise. The same account, the same edge, and the same unified data-transfer allowance cover both your tunnels and your deployed apps — one platform, one bill.
Try it
Install the agent and expose something you're running right now:
curl -fsSL https://ngris.com/install.sh | sh
ngris http 3000
Then, when you've got a static site or SPA to ship, deploy it to the same edge from the Static Apps guide and put a WAF or a login in front of it with a single rule. New here? Start with exposing localhost to the internet, then read deploying your app to the edge — two doors, one edge.
One edge for expose and deploy
Create a free account, run ngris http 3000, and ship your first static app — no credit card.
Frequently asked questions
What is the difference between exposing and deploying with Ngris?
Exposing (a tunnel) gives a public HTTPS URL to a service you are already running locally or in Kubernetes — run ngris http 3000 and the edge forwards traffic to your process. Deploying takes a front-end framework or static app, runs its install and build in a sandboxed job, and hosts the output on the same edge via a zip upload, a git push, or a quick-deploy API call. Both become the same kind of Ngris endpoint behind the same policy engine.
Can one tool both tunnel my localhost and host my static site?
Yes — that is the whole point of Ngris. Tunnels (expose) and app hosting (deploy) run on one two-sided edge platform with one account and one bill. ngrok only tunnels and Vercel or Netlify only deploy; Ngris does both behind a single policy edge with an AI that writes your rules.
Does Ngris deploy build React, Vite, or Vue apps?
Yes. Ngris Deploy runs your npm, yarn, or pnpm install and build in a sandboxed job and serves the output on the edge. It auto-detects (and lets you override) React (Create React App), Vite, Vue, Svelte and SvelteKit (static), Angular, Astro, Gatsby, Next.js static export, Nuxt generate, and Hugo, plus prebuilt static served as-is.
Does Ngris deploy support serverless functions or server-side rendering?
Server-side rendering: yes. Ngris runs a Next.js server (or any framework's server) as a managed backend — it detects and runs any Dockerfile, any language or framework, and auto-detects Go, Node, and Python backends even without one, building each in a sandboxed job and running it on the edge behind the same policy engine as your front end. Serverless / edge functions: no — there is no per-request FaaS runtime, so you deploy a long-running backend instead. Fully static output (Next.js static export, Nuxt generate) still deploys self-serve as a static bundle.
Can a deployed app get a database on Ngris?
Yes — a full-stack app (a static front end plus a backend Ngris runs in-cluster) can add a managed, MySQL-compatible database (MariaDB) from the Application detail page. Ngris provisions a dedicated schema and a least-privilege user scoped to just that schema, then injects the connection as DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD, and a mysql:// DATABASE_URL environment variable and redeploys the app to pick them up — there are no secrets to copy. It is MariaDB/MySQL only (not Postgres, Redis, or Mongo) and is a paid-plan feature (off on the free tier).
Is the same security available on both tunnels and deployed apps?
Yes. A deployed app and a tunneled service are both Ngris endpoints, so the same per-endpoint policy engine applies to either — a WAF, per-endpoint auth (OAuth/SSO, API keys), rate limits, IP allowlists, and live traffic inspection and replay are attached the same way regardless of which door you came in.
What does the Iris AI assistant actually do?
Iris drafts traffic-policy rules from plain English — firewall rules, rate limits, full traffic policies, routing rules, error templates, and metric alerts — and shows a confirmation card with a blast-radius dry-run before anything is applied. Writes beyond firewall rules require your approval; an opt-in autonomy mode is limited to firewall rules and auto-reverts. Iris also answers questions about your account — your endpoints, members and roles, plan entitlements and quotas, and verification status — by reading the live API rather than guessing, and it searches your HTTP traffic logs from a plain-English query and can compile a structured, downloadable account report.
Is Ngris self-hosted?
No. Ngris is a hosted SaaS platform running a managed multi-region edge with automatic TLS. You install a small agent for tunnels or push a build for deploys; you do not operate the edge yourself. Pricing is $0 to start, $8/mo for Team, and $25/mo for Enterprise.