Skip to content

Public tunnels

A Cloudflare quick tunnel gives a local site a public HTTPS URL — for a client review, a webhook that needs to reach you, or testing on a real phone.

Terminal window
rex tunnel start myshop.rex # prints the public URL
rex tunnel list
rex tunnel stop myshop.rex

cloudflared makes an outbound connection to Cloudflare and receives requests over it. Nothing listens on your machine, no port is opened, and no router configuration is involved — which is also why it works behind NAT and on a café network.

Sites on the shared nginx, on a FrankenPHP override and on an Apache override can all be tunnelled. The per-site override backends sit on loopback ports rather than behind the shared server, which used to put them out of reach.

The tunnels list has a search box that matches the site name, the domain and the public URL — because the question this page is uniquely able to answer is “which of my sites is https://odd-cat-42.trycloudflare.com?”, and pasting the link is how a person asks it.

A filter that hides a live public URL says so, in as many words — “2 shared sites are hidden by this filter — still public until you stop sharing” — rather than letting an exposed site disappear because you typed three letters.

WordPress writes its own URL into the database and into generated markup, so a site reached at a tunnel URL would otherwise serve links pointing back at https://myshop.rex — which resolves to nothing on your client’s machine.

rexenv rewrites for the tunnel while it is up, so shared links work — on the host the tunnel actually pins, and nowhere else.

For a multisite network there is a second half: a subdomain network is served as a subdirectory network while shared, because a quick tunnel has one hostname and no wildcard. See Multisite.

A public share is the only thing rexenv does that is visible from outside your machine, and until 0.4.0 starting one wrote nothing to the app-wide log — only failures and sweeps did. So when a share was found running that nobody remembered starting, the only evidence was in a per-tunnel log you would open only once you already knew which domain to suspect. Now a share logs its start — the site, the public URL, the pid and the origin it points at — and its end, so grep tunnels: rexenv.log answers “what was public, when, and which process”.

A site you have stopped can still be shared, and the app, the CLI and an agent all say the same one sentence when you do:

myshop.rex is stopped in rexenv, so this link shows the “site stopped” page to anyone who opens it. Start the site to serve it.

A warning, not a refusal: the visitor gets rexenv’s own stopped page, which is honest, and there are real reasons to want the URL standing before the site is. What it must never be is silent. The warning is recomputed wherever the share is reported rather than captured at start, because the site can be stopped after the tunnel exists.

The site, as it is, to anyone with the URL. Quick tunnel URLs are unguessable but not secret — they are not access control.

Do not tunnel a site holding real customer data, real credentials, or an unprotected admin account with a weak password. Local sites are usually configured far more loosely than production, and a tunnel makes that configuration reachable.

The tunnel needs the stack up first. rex status for the stack, rex doctor if something looks wrong. A failed tunnel names its reason rather than reporting a generic error.

An AI agent connected over MCP can start a share only with the Agent access dial at Full, for 30 minutes by default and 60 at most, and rexenv stops it on its own when the time is up or when it quits.