Self-Hosting with Cloudflare Tunnels
I run a handful of services on my home server — Gitea, a media server, some internal tools. For years I used port forwarding with dynamic DNS, which worked but always felt fragile and exposed.
Cloudflare Tunnels changed the game. The idea is simple: instead of opening ports inbound, you run a lightweight daemon (cloudflared) on your server that creates an outbound connection to Cloudflare’s edge. Traffic flows through Cloudflare to your service. Your public IP is never exposed.
Setup
Install cloudflared on the host:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
Authenticate and create a tunnel:
cloudflared tunnel login
cloudflared tunnel create homelab
Configure your routes in ~/.cloudflared/config.yml:
tunnel: your-tunnel-id
credentials-file: /home/user/.cloudflared/your-tunnel-id.json
ingress:
- hostname: gitea.yourdomain.com
service: http://localhost:3000
- hostname: media.yourdomain.com
service: http://localhost:8096
- service: http_status:404
Run it as a systemd service and forget about it.
Why This Matters
- Zero open ports on your router
- Cloudflare handles SSL termination
- DDoS protection comes free
- Access policies can require authentication before traffic even reaches your server
The only downside is you’re trusting Cloudflare as a middleman. For personal services, that tradeoff is easy to accept.