I run Open WebUI at home behind a Cloudflare Tunnel so I can hit my local Ollama setup from my phone without opening a single port on my router. Getting HTTPS and DNS working took ten minutes. Getting long-running chats to stop randomly dying mid-response took a lot longer than that, and that’s really the part worth writing about.
Quick Answer
- Install
cloudflared, create a tunnel, and point it athttp://localhost:8080(or your Docker service name if you’re running both in Compose) - Set
WEBUI_URLon the Open WebUI container to your public HTTPS domain, or OAuth callbacks and internal links will break - Long tool calls (web search, big RAG jobs) can hit Cloudflare’s 100-second idle timeout and throw a 524 error even though the chat finishes fine over WebSocket
- Don’t proxy your Ollama API directly through the same tunnel hostname as Open WebUI — keep them on separate ingress rules or it’ll silently fail to connect
- Docker Compose is the easiest setup if you’re already running Open WebUI in a container, since
cloudflaredcan reach it over the internal network with no exposed ports at all
Why Things Break Behind a Tunnel (Even When DNS Looks Fine)
Cloudflare Tunnel is genuinely a nice piece of engineering — it opens an outbound-only connection from your server to Cloudflare’s edge, so nothing on your home network needs a forwarded port. But Open WebUI isn’t a static site. It leans on WebSockets for live chat updates, long HTTP connections for streaming completions, and sometimes very long-running tool calls in the background. Tunnels and proxies were mostly designed with shorter request/response cycles in mind, and that mismatch is where most of the pain comes from.
A few specific things cause the majority of issues:
- Idle timeout on long requests. Cloudflare (like most commercial proxies) has a hard idle timeout around 100 seconds on connections that go quiet. If Open WebUI is running a slow tool call — a deep web search, a large document RAG pass — the underlying HTTP request can sit silent long enough to get killed by the proxy, even though the actual model response finishes fine and shows up through the WebSocket channel a moment later.
- WebSocket forwarding not being automatic. Older or misconfigured tunnel setups sometimes don’t forward WebSocket upgrades properly by default, which shows up as chat messages that seem to “hang” without ever completing, even though the backend logs show the request went through.
- Wrong internal port or service URL. This one’s dumb but common — pointing the tunnel at
localhost:8080when Open WebUI is actually only reachable inside a Docker network atopen-webui:8080(no localhost involved at all in that case). - Trying to tunnel Ollama’s API through the same public hostname as Open WebUI. From what I’ve seen in various setup threads, this trips people up constantly — Ollama’s API and Open WebUI’s frontend don’t behave the same way behind a proxied Cloudflare connection, and mixing them under one ingress rule causes connection failures that look like a WebUI bug but aren’t.
Setup Comparison: Native cloudflared vs Docker Compose
| Approach | Best For | Port Exposure | Setup Complexity |
|---|---|---|---|
Native cloudflared + local install | Servers already running Open WebUI outside Docker | None externally, uses localhost internally | Low |
| Docker Compose (both services) | Anyone running Open WebUI in Docker already | Zero, cloudflared reaches it via container network | Low-medium |
Quick tunnel (cloudflared tunnel --url) | Testing only, not production | None, but random .trycloudflare.com subdomain | Very low, but not durable |
Step-by-Step Setup
Step 1: Install cloudflared
On Linux:
curl -sSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflaredStep 2: Authenticate and Create the Tunnel
cloudflared tunnel login
cloudflared tunnel create open-webuiThis opens a browser to authorize the tunnel against your Cloudflare account, and it’ll print a Tunnel ID you’ll need in the next step. Write that ID down — you’ll want it in your config file.
Step 3: Configure Ingress Rules
Create ~/.cloudflared/config.yml:
tunnel: YOUR_TUNNEL_ID
credentials-file: /home/YOUR_USER/.cloudflared/YOUR_TUNNEL_ID.json
ingress:
- hostname: chat.your-domain.com
service: http://localhost:8080
- service: http_status:404That final catch-all rule matters — without it, cloudflared won’t start cleanly.
Step 4: Route DNS and Start the Tunnel
cloudflared tunnel route dns open-webui chat.your-domain.com
cloudflared tunnel run open-webuiCloudflare creates the DNS record automatically, and HTTPS is handled entirely on their end — no certificate management on your side at all.
Step 5: Set WEBUI_URL on the Container
This step gets skipped constantly and causes weird OAuth and internal link bugs later. Set it explicitly:
docker run -d \
-p 8080:8080 \
-e WEBUI_URL=https://chat.your-domain.com \
-v open-webui:/app/backend/data \
--name open-webui \
ghcr.io/open-webui/open-webui:mainStep 6 (Docker Compose Route): Run Both Services Together
If you’re already using Compose, this is honestly the cleanest option — no exposed ports at all, since cloudflared reaches Open WebUI over Docker’s internal network:
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
volumes:
- open-webui:/app/backend/data
environment:
- WEBUI_URL=https://chat.your-domain.com
restart: unless-stopped
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
command: tunnel --no-autoupdate run --token YOUR_TUNNEL_TOKEN
restart: unless-stopped
volumes:
open-webui:Grab the tunnel token from the Cloudflare dashboard under Networking → Tunnels → your tunnel → Add a replica → copy the install command, and point the ingress service URL at http://open-webui:8080 instead of localhost, since these two containers talk to each other by service name.
What Actually Worked For Me
The initial setup — DNS, HTTPS, basic chat working — took about ten minutes and honestly felt suspiciously easy. And then I tried running a web-search-enabled query with a slower model, and the chat just… hung. No error in the UI, no obvious crash, it just sat there spinning past the point where I’d normally expect a response.
My first guess was a WebSocket problem, since that’s the usual suspect with tunnels. I spent a good hour checking WebSocket upgrade headers and confirming socket.io connections were actually establishing (they were, according to the container logs). That wasn’t it.
The actual cause, it turned out, was the 100-second idle timeout on the underlying HTTP request during the tool-use phase — Open WebUI holds that connection open without sending any bytes while the search and retrieval happens in the background, and Cloudflare kills silent connections past that window. The response usually still showed up a few seconds later through the WebSocket channel, which made the whole thing more confusing, not less — half my test messages “failed” with a 524 in the browser console and then quietly succeeded anyway a moment after.
There’s no clean fix for this on the Open WebUI side yet as far as I can tell — it’s a known upstream issue, not something you can just toggle off. What helped in practice was keeping tool-use timeouts realistic (don’t ask for 15 web sources on a model that’s going to think for two minutes) and just mentally accepting that a 524 in the console doesn’t always mean the chat actually failed. Not a satisfying fix, but it’s the honest one.
Advanced Fixes and Edge Cases
Separating Ollama’s API from the WebUI hostname. If you’re running Ollama on a separate machine and want to reach it through the same tunnel, don’t route it under the same public hostname as Open WebUI. Give it its own ingress rule and its own subdomain, and keep the DNS record un-proxied (grey-clouded) rather than orange-clouded if you’re hitting connection issues — some setups only work when Cloudflare isn’t proxying the IP for that specific service.
Checking WebSocket delivery in the logs. If chat messages seem to hang, check your Open WebUI container logs for the /ws/socket.io/ handshake — you’re looking for a line showing "WebSocket ... [accepted]" followed by connection open. If you only ever see polling transport and never the upgrade to websocket, that’s your actual problem, and it usually points to a proxy or ingress misconfiguration rather than anything on the Open WebUI side.
Zero Trust access gating. If you want authentication in front of Open WebUI beyond its own login screen, Cloudflare Zero Trust → Access controls → Applications lets you gate the whole tunnel hostname behind an email or identity provider check before traffic even reaches your server. Worth doing if you’re exposing this to the public internet rather than just your own devices.
Blank screen after an update. A handful of users have reported a blank screen after updating the Open WebUI image while running behind a tunnel — usually resolved by a hard refresh or clearing the site’s service worker cache, not a tunnel-side issue at all, even though it happens right after touching the proxy config and looks related.
Prevention Tips
- Always set
WEBUI_URLexplicitly to your public HTTPS domain — don’t leave it on the container default - Keep Ollama’s API and Open WebUI’s frontend on separate ingress hostnames if you’re tunneling both
- Don’t be alarmed by an occasional 524 in the browser console during long tool calls — check the actual chat result before assuming it failed
- Update
cloudflaredperiodically; older versions have had WebSocket forwarding quirks that newer releases quietly fixed
FAQ
Do I need a domain name to use Cloudflare Tunnel? For the durable, named-tunnel setup, yes. For quick testing, cloudflared tunnel --url http://localhost:8080 gives you a random .trycloudflare.com address with no domain needed, but it’s not meant for anything long-term.
Why does my chat say it failed but then the response shows up anyway? That’s almost always the 100-second idle timeout hitting the HTTP request during a long tool call, while the actual result still arrives over the WebSocket connection a moment later.
Can I run Ollama and Open WebUI on different machines through one tunnel? Yes, but give them separate ingress hostnames. Trying to route both through one shared hostname is a common cause of “WebUI can’t connect to Ollama” errors.
Is Cloudflare Tunnel free? Yes for this use case — tunnels themselves don’t require a paid Cloudflare plan for basic setups like this one.
Editor’s Opinion
setup itself is genuinely easy, thats not the hard part. the hard part is the timeout weirdness on long tool calls and honestly i dont think theres a clean fix yet from the open webui side. if all you want is basic chat access from your phone youll probably never hit this. if you’re doing heavy web search or big rag jobs through it, just know the 524 in your console might be lying to you
