Connecting a Netlify Function to a Home Server via a Dynamic Cloudflare Tunnel
Description and use
A Netlify function dynamically retrieves the Cloudflare tunnel URL and proxies requests to a home server, removing the need for a static hostname.
Problem
How to call a home server from a Netlify function when the Cloudflare tunnel address changes on each restart?
Outcome
The solution allows a Netlify function to reliably call a home server behind a dynamic Cloudflare tunnel by querying the tunnel URL at runtime, eliminating the need for static hostnames or port forwarding.
Workflow
- Install cloudflared on the Pi and configure it to run as a background service without a static hostname.
- Start the tunnel with
cloudflared tunnel run myhome-tunnel &and note that Cloudflare assigns a random public URL. - Create a Cloudflare API token with Zone:Read and Tunnel:Read permissions and store it in Netlify’s environment variables (CLOUDFLARE_TOKEN).
- Write a Node script to call the Cloudflare API endpoint
https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/cfd_tunneland extract the tunnel_url for the tunnel named "myhome-tunnel". - Implement a Netlify function (
netlify/functions/ping-home.js) that: 1) fetches the tunnel URL from the Cloudflare API, 2) appends the desired path (e.g., /status), 3) forwards the request to the home server and returns the response to the client. - Store the Cloudflare account ID in Netlify’s environment variables (CLOUDFLARE_ACCOUNT_ID).
Evidence
I run a small automation server at home that powers a few cron jobs and a private API for my own website.
Cloudflare Tunnel (formerly Argo Tunnel) creates a secure outbound connection from my Pi to Cloudflare’s edge network.
I created a token with the Zone:Read and Tunnel:Read permissions scoped to my account.
The function runs on Netlify’s edge, so the outbound request must be over HTTPS. Cloudflare’s tunnel URL is always HTTPS, which satisfies that.
- Record date: 2026-10-27T13:26:12.633Z