Skip the Port Forwarding Headache
Running a self-hosted app – a personal Nextcloud instance, a Jellyfin media server, or a Home Assistant dashboard – usually means wrestling with port forwarding rules, dynamic DNS configs, and the quiet anxiety of exposing your home IP to the public internet. Cloudflare Tunnel cuts through all of that. It creates an outbound-only encrypted connection between your server and Cloudflare’s edge network, so your app becomes reachable from anywhere without opening a single port on your router or revealing your home IP address.
The tunnel works by running a lightweight daemon called cloudflared on your machine. That daemon maintains a persistent outbound connection to Cloudflare, and Cloudflare routes incoming HTTPS traffic through it to your local service. No inbound firewall rules. No exposed ports. No public IP in your DNS records. The setup takes roughly 20 minutes and the free tier covers most personal and small-team use cases without any cost.

What You Need Before Starting
Before touching any configuration, you need a domain name with its DNS managed by Cloudflare. This does not require you to buy a domain through Cloudflare – you can transfer DNS management of any existing domain to Cloudflare’s nameservers for free. Once your domain is active in the Cloudflare dashboard and showing a green “Active” status, you are ready to proceed. If your domain is still propagating or stuck in a pending state, the tunnel setup will complete but the DNS record creation step will silently fail.
You also need a machine running your self-hosted app – a Raspberry Pi, a home server, a VPS, or even a regular desktop running Linux or Windows. The cloudflared daemon is available as a binary for Linux (amd64, arm64, armv6), macOS, and Windows. For Docker environments, Cloudflare maintains an official container image at cloudflare/cloudflared, which makes integration with existing Docker Compose stacks straightforward.
Installing and Authenticating cloudflared
On a Debian or Ubuntu machine, the cleanest installation path uses Cloudflare’s own package repository. Add the GPG key and repository, then install via apt. The commands are available directly in the Cloudflare Zero Trust dashboard under the tunnel creation wizard – it generates the exact install commands for your architecture, which removes any guesswork about package sources. After installation, run cloudflared tunnel login from the terminal. This opens a browser window (or prints a URL if you are on a headless machine) where you authorize the daemon against your Cloudflare account and select which domain it can manage.
Once authenticated, cloudflared stores a certificate file in ~/.cloudflared/cert.pem. This certificate is what authorizes your machine to create and manage tunnels on that account. Keep it secure – anyone with that file can create tunnels under your Cloudflare account. From this point, create a named tunnel with cloudflared tunnel create my-tunnel, substituting whatever name makes sense for your setup. The command returns a tunnel UUID and writes a credentials JSON file to the same .cloudflared directory.

Configuring the Tunnel and DNS Routing
The tunnel configuration lives in a YAML file, typically at ~/.cloudflared/config.yml. At minimum, the file needs three fields: the tunnel UUID, the path to the credentials file, and an ingress block that maps hostnames to local service addresses. A basic ingress rule looks like this: you specify a hostname such as files.yourdomain.com, then point it to the local address your app listens on, for example http://localhost:8080. If the app uses a self-signed certificate on localhost, add noTLSVerify: true under that service’s origin request settings – otherwise cloudflared will refuse the connection. Every ingress block must end with a catch-all rule pointing to a 404 or 502 response so Cloudflare knows how to handle unmatched requests.
With the config file written, create the DNS record by running cloudflared tunnel route dns my-tunnel files.yourdomain.com. This creates a CNAME record in your Cloudflare DNS that points the subdomain to your tunnel’s unique address at [uuid].cfargotunnel.com. Because it is a CNAME to Cloudflare’s infrastructure rather than an A record pointing at your IP, your home address never appears in public DNS. You can add multiple hostname entries to the same tunnel – one tunnel can serve a dozen different subdomains each routing to different local ports.
Running the tunnel manually with cloudflared tunnel run my-tunnel is fine for testing, but for anything permanent you want it running as a system service. On Linux with systemd, cloudflared service install drops a unit file and enables it automatically. After a systemctl start cloudflared, the tunnel survives reboots and restarts itself on failure. On a Raspberry Pi running Home Assistant, for instance, this means your dashboard stays accessible through the tunnel even after power cuts or system updates – which is the same machine you might already be using if you followed a Home Assistant setup guide for smart device control.
One area worth spending extra time on is Cloudflare’s Access policies, available under the Zero Trust section of the dashboard. Without an Access policy in place, your tunnel makes the app publicly reachable – which may be exactly what you want for something like a public-facing portfolio site, but is a significant risk for a private file server or admin panel. Access lets you put an authentication layer in front of the tunnel: you can require a one-time email code, GitHub OAuth, or Google login before the app ever loads. The policy applies at Cloudflare’s edge before the request even reaches your machine, so it works regardless of whether the app has its own authentication built in.

There is one practical tradeoff that rarely gets mentioned in setup guides: all traffic to your self-hosted app now routes through Cloudflare’s network, which means Cloudflare can technically inspect unencrypted HTTP traffic between its edge and your origin if you disable end-to-end encryption. For personal use and low-sensitivity apps this is generally acceptable – and Cloudflare’s privacy policies explicitly prohibit them from selling traffic data – but for anything involving medical records, financial information, or private communications, the architecture deserves closer scrutiny than a 20-minute setup tutorial typically invites.





