cloudflare / cloudflare/cloudflare-docs

Add docs for how to use wrangler dev with cloudflare tunnels

Open
#28,227 3 comments 0 reactions 1 assignee Claimed by @irvinebroque View on GitHub
content:new documentation product:workers stale
Dominant language
MDX
Stars
5.2k
Forks
16.7k
Avg merge
2d 6h
Merged PRs (30d)
337

Description

### Proposed changes

# Expose your dev server with Cloudflare Tunnel

**Status:** Draft docs proposal
**Target location:** `developers.cloudflare.com/workers/development-testing/expose-dev-server/`
**Section:** Workers > Development & testing

---

## Problem

`wrangler dev` and `vite dev` (with the Cloudflare Vite plugin) start a local HTTP server on `localhost:8787`. This server is only reachable from your own machine. There's no documented way to share your local dev session with teammates, test from a mobile device, or receive webhooks from external services.

The Cloudflare Tunnel docs explain how to expose any local HTTP server. The Workers docs explain how `wrangler dev` works. But no page ties them together. You have to read both doc sets and figure out port matching, interface binding, and hot reload behavior yourself.

## Proposal

Add a new page under `/workers/development-testing/` that walks through exposing a `wrangler dev` (or `vite dev`) session with Cloudflare Tunnel.

---

## Plan

### Page placement

```
/workers/development-testing/
├── index.mdx (Development & testing overview)
├── local-data.mdx (Adding local data)
├── wrangler-vs-vite.mdx (Choosing between Wrangler & Vite)
├── bindings-per-env.mdx (Bindings per environment)
├── expose-dev-server.mdx ← NEW PAGE
└── ...
```

The new page sits as a sibling of `local-data.mdx` and `wrangler-vs-vite.mdx`. It covers an orthogonal concern (network access to your dev server) rather than modifying the existing local development or remote bindings content.

### Cross-links to add

| Location | Change |
| ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/workers/development-testing/index.mdx` | Add a link in the "Local development" section: "To share your dev server with others or receive external webhooks, see [Expose your dev server](/workers/development-testing/expose-dev-server/)." |
| `/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/` | Add Workers-specific example: "For example, to expose a `wrangler dev` session: `cloudflared tunnel --url http://localhost:8787`" |
| `/workers/wrangler/commands/#dev` | Add a note under the `--ip` and `--port` flags referencing the tunnel guide |

### Out of scope

- Changes to wrangler itself (no code changes)
- Tunnel configuration beyond what's needed for dev server use cases
- Zero Trust policy configuration (link out to existing docs)

---

## Draft docs page

Below is the full draft content for `expose-dev-server.mdx`.

---

````mdx
---
title: Expose your dev server
description: Share your local Workers dev server with others using Cloudflare Tunnel.
---

# Expose your dev server

When you run `wrangler dev` or `vite dev` (with the [Cloudflare Vite plugin](/workers/vite-plugin/)), your Worker runs on a local HTTP server bound to `localhost:8787`. This means only your machine can reach it.

To share your dev server with teammates, test from a mobile device, or receive webhooks from external services, you can use [Cloudflare Tunnel](/cloudflare-one/networks/connectors/cloudflare-tunnel/) to create a public URL that routes traffic to your local server.

## How it works

[`cloudflared`](/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/) runs alongside your dev server and creates an outbound-only connection to Cloudflare's network. Cloudflare assigns a public URL that proxies requests through this connection to `localhost:8787` on your machine.

Your dev server stays on `localhost`. `cloudflared` handles TLS termination at Cloudflare's edge and encrypts the tunnel connection automatically. Hot reload continues to work — `wrangler dev` uses a stable proxy on port `8787` that persists across code changes.

## Prerequisites

- [Install `cloudflared`](/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/) on your machine
- A working Workers project with `wrangler dev` or `vite dev` running

## Quick tunnel (no account required)

A [quick tunnel](/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/) generates a temporary public URL on `trycloudflare.com`. No Cloudflare account needed. Good for quick testing or sharing a preview link.

### 1. Start your dev server

```sh npx wrangler dev ```
```sh yarn wrangler dev ```
```sh pnpm wrangler dev ```
```sh npx vite dev ```

By default, this starts a server on `http://localhost:8787`.

### 2. Start a quick tunnel

In a separate terminal:

```sh
cloudflared tunnel --url http://localhost:8787
```
````

`cloudflared` prints a URL like `https://random-words.trycloudflare.com`. Anyone with this URL can reach your dev server.

### 3. Send requests to the public URL

```sh
curl https://random-words.trycloudflare.com
```

The request travels through Cloudflare's network, through the tunnel, and hits your local Worker.

:::note
Quick tunnels have a limit of 200 concurrent in-flight requests and do not support Server-Sent Events (SSE). For higher limits or persistent hostnames, use a named tunnel.
:::

## Named tunnel (persistent hostname)

A [named tunnel](/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/create-remote-tunnel/) gives you a stable hostname on your own domain. This requires a Cloudflare account with a domain.

### 1. Authenticate and create the tunnel

```sh
cloudflared tunnel login
cloudflared tunnel create my-worker-dev
```

### 2. Route DNS to the tunnel

```sh
cloudflared tunnel route dns my-worker-dev dev-worker.example.com
```

This creates a CNAME record pointing `dev-worker.example.com` to your tunnel.

### 3. Configure the tunnel

Create `~/.cloudflared/config.yml`:

```yaml
tunnel: my-worker-dev
credentials-file: ~/.cloudflared/.json

ingress:
- hostname: dev-worker.example.com
service: http://localhost:8787
- service: http_status:404
```

Replace `` with the UUID printed when you created the tunnel.

### 4. Start your dev server and tunnel

```sh
# Terminal 1
npx wrangler dev

# Terminal 2
cloudflared tunnel run my-worker-dev
```

Your Worker is now reachable at `https://dev-worker.example.com`.

### Restrict access

Anyone who knows the hostname can reach your dev server. To restrict access, [create a Cloudflare Access application](/cloudflare-one/applications/configure-apps/self-hosted-public-app/) for the hostname and configure a policy that limits access to your team.

## Configuration

### Port matching

The port in the `cloudflared` command (or config file) must match the port your dev server listens on. If you change the dev server port, update the tunnel to match:

```sh
# Dev server on port 3000
npx wrangler dev --port 3000

# Tunnel must point to the same port
cloudflared tunnel --url http://localhost:3000
```

### Interface binding

By default, `wrangler dev` binds to `localhost`. Since `cloudflared` runs on the same machine and connects to `localhost`, this works without changes. You do **not** need `--ip 0.0.0.0`.

Only use `--ip 0.0.0.0` if `cloudflared` runs on a different machine on your network:

```sh
npx wrangler dev --ip 0.0.0.0 --port 8787
```

### Using `--local` vs default mode

Use the default mode or `--local` — both run your Worker code locally, which is what you want when tunneling back to your machine. Do not use `--remote`, which uploads your code to Cloudflare's network and defeats the purpose of a tunnel to your local server.

### Custom port with Vite

When using the Cloudflare Vite plugin, configure the port in `vite.config.js`:

```js
import { defineConfig } from "vite";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
plugins: [cloudflare()],
server: {
port: 8787,
},
});
```

Then point `cloudflared` at the same port.

## Common use cases

| Use case | Approach |
| ---------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Share a preview link with a teammate | Quick tunnel — send them the `trycloudflare.com` URL |
| Test from a mobile device on the same network | Quick tunnel or named tunnel — open the URL on your phone |
| Receive webhooks from an external service (Stripe, GitHub, etc.) | Quick tunnel or named tunnel — set the webhook URL to the tunnel hostname |
| Persistent dev environment for a team | Named tunnel with a stable hostname and an Access policy |

## Limitations

- Quick tunnels generate a new URL each time you restart `cloudflared`. For stable URLs, use a named tunnel.
- Quick tunnels are capped at 200 concurrent in-flight requests.
- Quick tunnels do not support Server-Sent Events (SSE).
- If you have an existing `~/.cloudflared/config.yaml`, quick tunnels may not work. Rename the file temporarily or use a named tunnel instead.
- Tunnel latency adds round-trip time to every request. This is fine for development but not representative of production performance.

```

---

## Summary of changes

| File | Action |
|---|---|
| `src/content/docs/workers/development-testing/expose-dev-server.mdx` | **New page** — full content above |
| `src/content/docs/workers/development-testing/index.mdx` | **Edit** — add link to new page in the "Local development" section |
| Sidebar config for Workers docs | **Edit** — add `expose-dev-server` entry under `development-testing` |
| `src/content/docs/cloudflare-one/.../trycloudflare.mdx` | **Edit** — add Workers example to "use cases" section |
| `src/content/docs/workers/wrangler/commands.mdx` | **Edit** — add note under `--port` flag linking to the tunnel guide |
```

### Subject Matter

Cloudflare Tunnels x wrangler

### Content Location

https://developers.cloudflare.com/workers/development-testing/

### Additional information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.