← All projects

Expose a Pi Service with Cloudflare Tunnel

Medium · ~45 minutes · Any Pi, plus a free Cloudflare account

Cloudflare Tunnel (formerly Argo Tunnel) lets you publish a service running on your Pi to a public hostname without opening ports on your router, getting a static IP, or running dynamic DNS. The Pi makes an outbound connection to Cloudflare; clients hit Cloudflare; Cloudflare proxies through the tunnel.

Why this beats port-forwarding: nothing on your home network is directly reachable from the internet. If the tunnel goes down, the service just becomes unavailable — no exposed surface to scan or exploit.

You'll need

1. Install cloudflared on the Pi

curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb

Use cloudflared-linux-armhf.deb instead if you're on a 32-bit OS (older Pi Zero W, Pi 1/2).

2. Log in

cloudflared tunnel login

This prints a URL. Open it on any device, sign in to Cloudflare, and authorize the domain you want to use. A cert file lands in ~/.cloudflared/.

3. Create a tunnel

cloudflared tunnel create pi-home

It returns a tunnel UUID and writes credentials to ~/.cloudflared/<uuid>.json. Note both — you'll need them.

4. Configure routing

Create ~/.cloudflared/config.yml:

tunnel: <uuid-from-step-3>
credentials-file: /home/pi/.cloudflared/<uuid>.json

ingress:
  - hostname: home.example.com
    service: http://localhost:8080
  - service: http_status:404

The final catch-all rule is required — without it, cloudflared refuses to start.

5. Bind the hostname

cloudflared tunnel route dns pi-home home.example.com

This creates a CNAME in your Cloudflare DNS pointing the hostname at the tunnel.

6. Run it as a service

sudo cloudflared service install
sudo systemctl enable --now cloudflared

Now it starts on boot. Visit https://home.example.com — you should hit your local service through Cloudflare.

Troubleshooting