01The Port Forwarding Problem
Traditional self-hosting requires opening ports on your router and pointing DNS records at your home IP address. This works, but it comes with real downsides: your home IP is exposed, you need to handle DDoS protection yourself, your ISP might block ports or change your IP, and every open port is a potential attack surface.
Cloudflare Tunnels flip this model. Instead of exposing ports to the internet, you run a lightweight connector (cloudflared) on your server that creates an outbound connection to Cloudflare's network. Traffic flows through Cloudflare to your tunnel to your service. No inbound ports, no exposed IP, and you get Cloudflare's DDoS protection and WAF for free.
I switched from port forwarding to Cloudflare Tunnels a year ago and it simplified my networking dramatically. No more dynamic DNS, no more router configuration, no more worrying about ISP port blocking.
02Setting Up Cloudflare Tunnel with Docker
You need a Cloudflare account (free tier works) and a domain managed by Cloudflare DNS. Create a tunnel in the Cloudflare Zero Trust dashboard, and you'll get a tunnel token.
[docker-compose.yml]
1services: 2 cloudflared: 3 image: cloudflare/cloudflared:latest4 container_name: cloudflared5 restart: unless-stopped6 command: tunnel --no-autoupdate run7 environment: 8 - TUNNEL_TOKEN=${CF_TUNNEL_TOKEN}9 networks: 10 - proxy1112networks: 13 proxy: 14 external: true03Routing to Your Services
Configure routes in the Cloudflare dashboard or via config file. Each route maps a public hostname to an internal service:
cloud.yourdomain.com → http://nextcloud:80
git.yourdomain.com → http://gitea:3000
grafana.yourdomain.com → http://grafana:3000
The cloudflared container needs to be on the same Docker network as the services it's routing to. Since we use the shared proxy network, it can reach any service connected to that network by container name.
The beauty of this approach is that your services don't need to bind to the host network at all. Remove the ports directive from your compose files entirely — traffic flows through the tunnel, not through exposed ports.
You can run Cloudflare Tunnels alongside a reverse proxy like Traefik. Point the tunnel at Traefik, and let Traefik handle routing, middleware, and SSL termination internally.
04Adding Access Policies
Cloudflare Zero Trust lets you add authentication in front of your tunnels. You can require login via Google, GitHub, one-time PIN, or other identity providers before anyone reaches your service. This adds a layer of protection even before traffic reaches your server.
For public services (a blog, a public API), set the route to bypass access policies. For private services (admin panels, monitoring), require authentication. This gives you the same tiered security as Authelia but managed entirely in Cloudflare's dashboard.
The free tier includes 50 users, which is more than enough for personal use. It's one of the best free tools available for self-hosters.
Browse our security category for Docker Compose configurations that include Cloudflare Tunnel setup alongside other networking solutions.