Exposing Homelab through Cloudflare Tunnel

Published: (December 30, 2025 at 05:42 PM EST)
4 min read
Source: Dev.to

Source: Dev.to

I love self‑hosting. I run my own blog, dashboards, and random experiments from my own server. What I don’t love is port forwarding, ISP NAT, dynamic IPs, and exposing my router to the entire Internet.

Thankfully, Cloudflare has a solution for this called Cloudflare Tunnel. It lets me expose services publicly without opening a single inbound port on my router. This post is how I actually use it in production.

The Problem with “Traditional” Self‑Hosting

The classic approach looks like this:

flowchart LR
    Internet --> Router
    Router --> Server

That means:

  • Open ports on the router
  • Trust your firewall configuration
  • Hope the IP doesn’t change
  • Become a soft DDoS target

For a homelab or personal server, this is a recipe for disaster and it isn’t a scalable solution.

The Cloudflare Tunnel Approach

With Cloudflare Tunnel the direction changes. Instead of the Internet coming into my network, my server reaches out.

flowchart LR
    User --> Cloudflare
    Cloudflare --> Tunnel
    Tunnel --> Server

Now my server only makes outbound connections to Cloudflare, and Cloudflare sits in the front as the public edge. This is much more secure: there are no open ports and no public IP is needed, removing an entire category of risk.

What Actually Runs on My Server?

On my server I run a small daemon called cloudflared.

flowchart TB
    cloudflared --> CloudflareEdge
    CloudflareEdge --> LocalService1
    CloudflareEdge --> LocalService2

cloudflared then:

  • Opens an encrypted tunnel to Cloudflare
  • Authenticates using my account credentials
  • Routes traffic internally to localhost

Therefore my apps never touch the public Internet directly.

Installing cloudflared

On Linux it takes about a minute to install cloudflared:

curl -fsSL https://pkg.cloudflare.com/install.sh | sudo bash
sudo apt install cloudflared

Quick sanity check:

cloudflared --version

Note: It’s often better to download the binary from the official website and install it manually; this way you control updates.

Authenticating My Server

To authenticate the server, run:

cloudflared tunnel login

A browser window opens, prompting you to log in to your Cloudflare account, select a domain, and approve the connection. Credentials are stored locally in ~/.cloudflared/cert.pem for future tunnels.

Creating the Tunnel

Create a tunnel with:

cloudflared tunnel create 

Cloudflare returns a UUID for the tunnel and a URL to download a configuration file. Save that file as ~/.cloudflared/.json. This file is the identity of the server.

My Tunnel Configuration (Example)

A simplified version of the configuration file:

tunnel: 
credentials-file: ~/.cloudflared/.json

ingress:
  - hostname: blog.example.com
    service: http://localhost:8080
  - hostname: dashboard.example.com
    service: http://localhost:8081
  - service: http_status:404

This creates one tunnel that routes multiple hostnames to different services on the server, with a safe fallback (http_status:404).

How Traffic Flows End‑to‑End

Full picture:

flowchart LR
    User --> DNS
    DNS --> Cloudflare
    Cloudflare --> Tunnel
    Tunnel --> ReverseProxy
    ReverseProxy --> App

Conceptually:

sequenceDiagram
    participant User
    participant Cloudflare
    participant Tunnel
    participant Server

    User->>Cloudflare: HTTPS request
    Cloudflare->>Tunnel: Forward request
    Tunnel->>Server: Local HTTP
    Server-->>Tunnel: Response
    Tunnel-->>Cloudflare: Encrypted response
    Cloudflare-->>User: HTTPS response

From the outside it behaves like a normal HTTPS connection, but the traffic is encrypted end‑to‑end, and on the server it appears as localhost traffic.

DNS: No Manual Records Needed

Cloudflare Tunnel automatically creates the necessary DNS records. It adds a CNAME that points your domain to Cloudflare’s edge. Run:

cloudflared tunnel route dns

…and that’s it! Cloudflare handles the rest.

Running the Tunnel Permanently

First test the tunnel:

cloudflared tunnel run 

When it works, install it as a system service:

sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

Now it starts on boot, restarts on failure, and runs as a non‑root user.

Adding Authentication

For anything private (admin panels, dashboards), I add Cloudflare Access policies to require authentication before the request reaches the tunnel. This ensures that only authorized users can reach those services.

Cloudflare Access

Which lets me:

  • Require login before accessing the service
  • Restrict by email or identity provider
  • Protect internal tools without VPNs

So from the outside, my dashboard looks public, but in reality it’s locked behind authentication.

My Production Setup

This is the layout I actually recommend:

flowchart LR
    User --> Cloudflare
    Cloudflare --> Tunnel
    Tunnel --> ReverseProxy
    ReverseProxy --> Blog
    ReverseProxy --> Dashboard
    ReverseProxy --> Admin

Why this works so well?
Cloudflare handles edge security, while my reverse proxy handles routing. The apps stay internal and “dumb,” and there are zero inbound ports.

Common Mistakes I’ve Made (So You Don’t Have To)

  • Exposing apps directly instead of through a reverse proxy
  • Forgetting a 404 ingress rule
  • Running admin panels without Access
  • Binding services to 0.0.0.0 unnecessarily instead of localhost

Rule of thumb:
If it’s not meant to be public, keep it on localhost. If it’s meant to be public, use Cloudflare Access.

Final Thoughts

While Cloudflare Tunnel is a powerful tool, it’s not a silver bullet. It’s just one piece of the puzzle. Combine it with other security measures—like Cloudflare Access—to keep your server secure.

Don’t use it for services such as:

  • Latency‑sensitive services
  • Game servers
  • Full‑network access (I use WireGuard for that)

For HTTP(S) apps, however, it’s my default. For personal servers and homelabs, this is one of the cleanest setups you can run today.

Back to Blog

Related posts

Read more »

AI SEO agencies Nordic

!Cover image for AI SEO agencies Nordichttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads...