> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cnap.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare Tunnel

> Use your own Cloudflare account to route custom domains to your cluster — no public IPs required

Cloudflare Tunnel lets you expose applications on your own custom domains through Cloudflare's network. Unlike [preview domains](/networking/preview-domains) where CNAP manages everything, here you bring your own Cloudflare account and control the tunnel configuration — access policies, WAF rules, caching, and everything else Cloudflare offers.

Your worker nodes don't need public IP addresses. A <Tooltip headline="cloudflared" tip="The Cloudflare Tunnel agent. It runs on your cluster and creates an outbound-only connection to Cloudflare's edge network. Since the connection is outbound, no firewall rules or open ports are needed.">cloudflared</Tooltip> agent on your cluster establishes an outbound connection to Cloudflare's edge, and Cloudflare routes incoming requests through the tunnel to your apps.

```
Browser → Cloudflare Edge (TLS + DDoS protection) → Tunnel → Your Cluster → App
```

## Why use this

* **No public IPs needed** — cloudflared connects outbound from your cluster. No firewall rules, no port forwarding, no exposed nodes
* **Your domain, your Cloudflare account** — full control over DNS, caching, access policies, WAF rules, and tunnel settings
* **Cloudflare Edge** — TLS termination, DDoS protection, and global edge caching come built-in
* **Works anywhere** — behind NAT, corporate firewalls, private networks — as long as the cluster has outbound internet access
* **Native Gateway API** — uses standard Kubernetes <Tooltip headline="Gateway API" tip="Gateway API is the Kubernetes standard for managing external traffic routing. It replaces older Ingress resources with a more expressive, role-oriented model.">Gateway API</Tooltip> resources, so the same HTTPRoute configuration works whether you're using Cloudflare Tunnel or another gateway

## How it works

CNAP deploys a Gateway API controller to your cluster that bridges Kubernetes routing with Cloudflare Tunnels. When you create an <Tooltip headline="HTTPRoute" tip="An HTTPRoute is a Gateway API resource that matches incoming HTTP requests by hostname and path, then routes them to a Kubernetes Service.">HTTPRoute</Tooltip> (either through CNAP's UI or a Helm chart), the controller automatically:

1. Creates a Cloudflare Tunnel and deploys the cloudflared agent
2. Pushes the hostname and path routing rules to Cloudflare's tunnel configuration
3. Creates DNS records (CNAME pointing your domain to the tunnel)

Routing updates happen within seconds — cloudflared pulls its configuration from Cloudflare, so new hostnames become reachable almost immediately.

## Setup

<Steps>
  <Step title="Deploy a Cloudflare gateway">
    From your cluster's detail page, deploy a **Cloudflare Tunnel** gateway. This installs the Gateway API controller and creates the base Gateway resource on your cluster.
  </Step>

  <Step title="Provide your Cloudflare credentials">
    Add your Cloudflare API token in the CNAP dashboard under your cluster's settings. You'll need a token with two permissions:

    | Permission                  | Scope   | Why                                   |
    | --------------------------- | ------- | ------------------------------------- |
    | **Cloudflare Tunnel: Edit** | Account | Create and manage tunnels             |
    | **DNS: Edit**               | Zone    | Create CNAME records for your domains |

    Credentials are stored centrally in CNAP — not on your cluster. You can rotate or update your token from the dashboard at any time without touching the cluster.
  </Step>

  <Step title="Expose your app with a custom hostname">
    For Docker and GitHub apps, go to **Settings > Ports**, toggle **Expose externally**, and enter your custom domain (for example, `app.yourdomain.com`).

    For custom Helm charts, configure the HTTPRoute hostname through the chart's own values.

    The controller detects the new HTTPRoute, updates the tunnel configuration, and creates a CNAME record pointing your domain to the tunnel.
  </Step>

  <Step title="Verify">
    Open `https://app.yourdomain.com` in your browser. Cloudflare handles TLS automatically — no certificate setup needed on your side.
  </Step>
</Steps>

## Compared to preview domains

Both preview domains and Cloudflare Tunnel use Cloudflare's network to route traffic to your cluster. The difference is who manages the configuration:

|                         | Preview Domains               | Cloudflare Tunnel                            |
| ----------------------- | ----------------------------- | -------------------------------------------- |
| **Domain**              | `*.cnap.app` (auto-generated) | Your own domain                              |
| **Cloudflare account**  | CNAP's account                | Your account                                 |
| **DNS**                 | Automatic                     | Automatic (controller creates CNAME)         |
| **TLS**                 | Automatic                     | Automatic (Cloudflare Edge)                  |
| **Tunnel config**       | Managed by CNAP               | Managed by CNAP with your credentials        |
| **Cloudflare settings** | None — fully managed          | Full control (WAF, caching, access policies) |

If you don't need a custom domain or Cloudflare-level configuration, [preview domains](/networking/preview-domains) are the fastest way to get a public URL.

## Under the hood

**Same controller, different credentials.** Cloudflare Tunnel and [preview domains](/networking/preview-domains) share the same Gateway API controller on your cluster. The difference is whose Cloudflare account is used. For preview domains, CNAP uses its own account. For custom domains, CNAP uses the credentials you provide in the dashboard. The controller doesn't know the difference — it calls CNAP's API, and CNAP routes to the right Cloudflare account.

**CNAP acts as a proxy.** The controller on your cluster never calls the Cloudflare API directly. Instead, it sends routing updates to CNAP's API, which forwards them to Cloudflare using your stored credentials. This means credential rotation happens in the dashboard — no cluster access needed, no Secrets to update. It also gives CNAP a complete picture of every tunnel and route across all your clusters, which enables reliable cleanup even if a cluster becomes unreachable.

**One tunnel per Gateway.** Each Gateway resource on your cluster maps to one Cloudflare Tunnel. The controller deploys a `cloudflared` agent (Kubernetes Deployment) that connects to Cloudflare using a scoped tunnel token. Multiple `cloudflared` replicas can connect to the same tunnel for high availability — Cloudflare load-balances across them automatically.

**DNS records are automatic.** When the controller detects an HTTPRoute with a hostname, it creates a proxied CNAME record (`app.yourdomain.com → {tunnel-id}.cfargotunnel.com`) via CNAP's API. Cloudflare resolves the CNAME to their nearest edge, terminates TLS, and forwards the request through the tunnel. The `cloudflared` agent routes it to the correct Kubernetes Service based on the hostname and path.

**<Tooltip headline="Remote vs Local Config" tip="Cloudflare Tunnels support two config modes: remote (routes pushed to CF API, visible in dashboard) and local (routes in a config file on the cluster). CNAP uses remote config for custom domain tunnels so routes appear in your Cloudflare dashboard. Preview domains use local config since there's no customer dashboard involved.">Remotely-managed</Tooltip> tunnel config.** The tunnel's routing rules are pushed to Cloudflare's configuration API — `cloudflared` pulls its config from Cloudflare rather than reading a local config file. This means routing updates propagate within seconds without restarting the agent. Because routes are managed through Cloudflare's API, they appear in your Cloudflare dashboard under the tunnel's public hostname tab — giving you full visibility into what's exposed alongside your other Cloudflare settings.

## Related topics

* [External access overview →](/networking) — Compare all options for exposing apps
* [Preview domains →](/networking/preview-domains) — Instant URLs without DNS setup, managed by CNAP
* [Direct IP →](/networking/direct-ip) — Route directly to worker node IPs
