Devops

Cloudflare Tunnels for Dev Projects — Quick Setup Guide

Published 2026-07-22 ~456 words Tags: cloudflare, tunnels, hosting, networking

Cloudflare Tunnels let you expose any web service to the internet without opening firewall ports, configuring NAT, or dealing with ISP blocks. They're free, fast, and dead simple to set up.

Why Tunnels?

Traditional hosting involves port forwarding, static IPs, and DNS propagation waits. Tunnels bypass all of that:

  • No open ports — The tunnel initiates outbound. Your firewall stays closed.
  • Random ports work — Running something on port 8897? The tunnel doesn't care.
  • HTTPS automatically — Cloudflare handles the cert.
  • Free — Up to 100 tunnels, no charge.

The One-Liner

The quickest way to get started on any machine:

curl -sL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared
chmod +x cloudflared
./cloudflared tunnel --url http://localhost:8897

This creates a random *.trycloudflare.com URL pointing to your local service. For development and demos, that's all you need.

Permanent Tunnels

For a permanent tunnel (like a production site), you need to authenticate once:

cloudflared tunnel login

This opens a browser to authorize your Cloudflare account. Then create a tunnel:

cloudflared tunnel create my-project

This generates a credentials file and a tunnel ID. Now configure it:

# ~/.cloudflared/config.yaml
tunnel: <tunnel-id>
credentials-file: /root/.cloudflared/<tunnel-id>.json
ingress:
  - hostname: myproject.com
    service: http://localhost:8897
  - service: http_status:404

Point your DNS at the tunnel:

cloudflared tunnel route dns my-project myproject.com

Then run it:

cloudflared tunnel run my-project

Running as a Service

For production, run it as a systemd service:

cloudflared service install

It auto-restarts on failure, logs to journald, and stays out of your way. Check status with:

systemctl status cloudflared

Per-Project Ports

A useful pattern: run each project on a different local port, then point a separate tunnel at each one:

| Project | Local Port | Tunnel Hostname | |---|---|---| | handycanadian.ca | 8897 | handycanadian.ca | | unofficialtutorials.com | 8898 | unofficialtutorials.com | | flashmart.ca | 8899 | flashmart.ca |

This keeps everything isolated. If one project crashes, it doesn't affect the others. You just restart that single cloudflared tunnel.

The One Catch

Since Cloudflare acts as a reverse proxy, your access logs show Cloudflare's IPs, not the visitor's real IP. You need to configure your web server to read the CF-Connecting-IP header for real visitor IPs.

In Apache, add to your config:

RemoteIPHeader CF-Connecting-IP
RemoteIPTrustedProxy 173.245.48.0/20

In PHP:

$realIp = $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'];

Tear Down

When you're done with a project:

cloudflared tunnel delete my-project
cloudflared tunnel route dns remove my-project myproject.com

That's it. No stale DNS records, no orphaned ports, no lingering infrastructure.

Summary

Cloudflare Tunnels are the simplest way to put a project online. One curl command for quick tests, a few config lines for permanent setups. Free, secure, and works with anything running on any port.