DEV Community

Laxman Patel
Laxman Patel

Posted on

🚀 How I Hosted a Website Locally Using NGINX + Cloudflare Tunnel + Custom Domain

Two days ago, I bought a .cfd domain for ₹89 on impulse. I didn’t have a hosting plan. No VPS. No static IP. No plan, really.

But I did have one goal:

👉 "Can I host a secure, public-facing website straight from my local machine... without exposing my IP or touching router configs?"

Turns out, yes. Yes, I can. Here's how — and more importantly, why I did it this way.


🧠 The Problem Space

I wanted:

  • To run a simple NGINX-powered static site
  • No monthly hosting bills
  • HTTPS (because insecure URLs scream "hobby project")
  • And ideally, a solution that "just works" — no duct tape

But I didn’t have:

  • A static IP
  • Control over my ISP’s router for port forwarding
  • Budget for VPS hosting

🧪 My First Thought: Ngrok?

Of course, I thought of Ngrok. It's the OG local tunnel tool. Dead simple. Plug and play.

But there were issues:

  • Free version rotates URLs — not great for a custom domain
  • Their custom domain support is behind a paid plan
  • Limited concurrent tunnels

I needed more control. I wanted my domain to point to my machine — directly and reliably.


☁️ Enter: Cloudflare Tunnel

I was already using Cloudflare for DNS, so I dug deeper and found cloudflared.

This tool lets you:

  • Expose your local server to the internet securely
  • Use your own domain name
  • Terminate HTTPS at the edge (no messing with certs)
  • Skip firewall config, port forwarding, and NAT struggles

And it’s 100% free.


🛠️ The Stack I Used

What Tool Used Why I Picked It Alternatives Considered
Domain .cfd from Hostinger Cheap (₹89) + DNS manageable Namecheap
Web Server NGINX on Ubuntu Lightweight, battle-tested Apache, Caddy
Tunnel cloudflared (FIPS) Secure, free, native domain support Ngrok, LocalTunnel
DNS Provider Cloudflare Fast, robust, full control GoDaddy, Namecheap

🔧 How I Did It (The Short Version)

  1. Bought the domain: goobara.cfd (because why not?)
  2. Pointed its NS records to Cloudflare
  3. Waited ~2 hours for DNS propagation (it will test your patience)
  4. Installed cloudflared
  5. Created and configured a tunnel
   cloudflared tunnel create goobara
   cloudflared tunnel route dns goobara goobara.cfd
   cloudflared tunnel run goobara
Enter fullscreen mode Exit fullscreen mode

6.Set up NGINX to serve localhost:80
7.Boom — goobara.cfd was live!

🧠 A Few "Aha!" Moments

  • curl -H "Host: goobara.cfd" http://localhost became my best friend.
  • My site didn’t work initially — turns out, I hadn’t removed Hostinger's default DNS records (rookie mistake).
  • Even though cloudflared showed success, DNS propagation + caching can cause confusion. Always verify with:dig goobara.cfd +short

💡 Why This Setup Rocks

  • No need for public IP
  • No Certbot / Let's Encrypt headaches
  • Minimal attack surface (everything is proxied through Cloudflare)
  • Zero cost hosting for hobby projects, dashboards, or even staging apps

Top comments (2)

Collapse
 
ujjwalvivek profile image
Ujjwal Vivek

Really clever solution! 👏

Love how you bypassed all the traditional hosting headaches. The cloudflared tunnel approach is so much cleaner than fighting with port forwarding and dynamic IPs.

Quick thought - have you considered setting up any monitoring/alerting for when your local machine goes down? Or maybe a simple health check script?

This setup could be perfect for home lab dashboards and staging environments. Thanks for the detailed walkthrough!

One question though - how's the performance been with your home upload speeds as the bottleneck?

Collapse
 
imlucky883 profile image
Laxman Patel

Hey, this was just a weekend experiment to test out cloudflared tunnels and see how cleanly I could expose local services without touching router configs. So I didn’t set up any monitoring/alerting — just a quick prototype for now.

As for performance — you're right, upload speed is the limiting factor, especially for anything media-heavy. For basic dashboards and dev UIs, it’s totally usable.