tech/cloudflare/tunnel

TUNNEL

Cloudflare Tunnel — secure outbound connector from on-premise to Cloudflare edge.

production Cloudflare Tunnel (cloudflared), any OS
improves: tech/cloudflare

Cloudflare Tunnel

Tunnel creates a secure outbound-only connection from any server or machine to Cloudflare's edge. The cloudflared daemon initiates the connection — no inbound firewall rules needed.

Free — the cloudflared binary is open source.

Install cloudflared

# macOS
brew install cloudflare/cloudflare/cloudflared

# Linux (Debian/Ubuntu)
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb

Create a tunnel (run once per server)

cloudflared tunnel login          # opens browser, authorises your CF account
cloudflared tunnel create my-tunnel
# → prints tunnel ID (UUID)

# Create a config file at ~/.cloudflared/config.yml

config.yml

tunnel: <TUNNEL-UUID>
credentials-file: /root/.cloudflared/<TUNNEL-UUID>.json

ingress:
  # Expose an on-premise ERP on a private hostname
  - hostname: erp-client.internal.2nth.ai
    service: http://localhost:8069

  # Expose a local Postgres via TCP (for Hyperdrive)
  - hostname: db-client.internal.2nth.ai
    service: tcp://localhost:5432

  # Catch-all — must be last
  - service: http_status:404

Run the tunnel

# One-off (dev)
cloudflared tunnel run my-tunnel

# As a system service (production)
cloudflared service install
systemctl start cloudflared

Calling the tunnelled service from a Worker

Once the tunnel is running and the hostname is proxied through Cloudflare:

// Worker calling a client's on-premise ERP
const response = await fetch('https://erp-client.internal.2nth.ai/api/method/frappe.client.get', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `token ${env.ERP_API_KEY}`,
  },
  body: JSON.stringify({ doctype: 'Sales Order', name: 'SO-001' }),
});

2nth Usage Pattern — Client SOR Access

For clients with on-premise ERP (Frappe/ERPNext, Sage X3 on Windows), the deployment pattern is:

  1. Install cloudflared on the client's ERP server
  2. Create a tunnel pointing to the ERP HTTP/HTTPS port
  3. Assign a private hostname under the client's Cloudflare zone
  4. Workers call the private hostname — traffic never leaves Cloudflare's network

This avoids VPN setup and doesn't require the client to open firewall ports.

Common Gotchas

See Also