TL;DR: Use Cloudflare Tunnel to make your home server accessible from anywhere. Free, secure, no router configuration needed.
I recently deployed a web app running on my laptop to a real domain. No cloud hosting, no VPS, no monthly bills. Just my laptop, a domain, and Cloudflare Tunnel.
Here's exactly how I did it.
The Problem
I wanted to host my side project on my own hardware. Sounds simple, right?
But my setup had issues:
- No access to the main router's admin panel
- Dynamic IP address
- Port forwarding wasn't an option
Traditional solutions like opening ports 80/443 weren't going to work.
The Solution: Cloudflare Tunnel
Cloudflare Tunnel (formerly Argo Tunnel) creates an outbound connection from your server to Cloudflare's edge. No incoming ports needed.
Internet → Cloudflare (SSL) → Tunnel → Your laptop
It's free, handles SSL automatically.
Prerequisites
- A domain name (any registrar works)
- A Cloudflare account (free tier is fine)
- A Linux/Mac/Windows machine running your app
- ~10 minutes
Step 1: Add Your Domain to Cloudflare
- Go to dash.cloudflare.com
- Click Add a site
- Enter your domain (e.g.,
myapp.com) - Select the Free plan
- Cloudflare will show you new nameservers
Step 2: Update Nameservers
Go to your domain registrar and replace the nameservers with Cloudflare's.
For example, if you're using Porkbun:
- Go to Domain Management → Your domain
- Click Nameservers → Edit
- Replace with Cloudflare nameservers:
carter.ns.cloudflare.com
vita.ns.cloudflare.com
- Save and wait 5-30 minutes for propagation
Step 3: Create a Tunnel
- In Cloudflare, go to Zero Trust (left sidebar)
- Navigate to Networks → Tunnels
- Click Create a tunnel
- Name it something like
my-server - You'll get an installation command with a token
Step 4: Install Cloudflared
On your server, install the cloudflared daemon:
Ubuntu/Debian:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
macOS:
brew install cloudflared
Windows:
Download from GitHub releases
Step 5: Connect the Tunnel
Run the command Cloudflare gave you:
sudo cloudflared service install <YOUR_TOKEN>
This installs cloudflared as a system service that starts automatically on boot.
Check it's running:
sudo systemctl status cloudflared
Step 6: Add a Public Hostname
Back in Cloudflare Dashboard:
- Go to your tunnel → Configure
- Click Public Hostname → Add a public hostname
- Fill in:
-
Subdomain: leave empty (or use
www) - Domain: select your domain
-
Service Type:
HTTP -
URL:
localhost:80(or whatever port your app runs on)
-
Subdomain: leave empty (or use
- Save
Note: If you get "DNS record already exists" error, delete the existing A record for your domain in DNS → Records first.
Step 7: Test It
Open your domain in a browser. It should load your local app with HTTPS!
# Or test from command line
curl https://myapp.com
Running Multiple Services
You can route different domains or paths to different local services:
| Domain | Service |
|---|---|
myapp.com |
localhost:3000 (frontend) |
api.myapp.com |
localhost:8080 (API) |
Just add multiple public hostnames in the tunnel configuration.
My Setup
Here's what I'm running:
textstack.app → localhost:80 → nginx → React frontend
textstack.app/api → localhost:80 → nginx → Docker API (port 8080)
textstack.dev → localhost:80 → nginx → Same app, different site
All from a laptop sitting in my living room.
Security Tips
- Firewall: Only allow necessary ports locally
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # For tunnel (local only)
sudo ufw enable
Don't expose admin panels to the internet. Keep them on
localhostonly.Cloudflare adds SSL automatically - no need for Let's Encrypt.
Use Access Policies (in Zero Trust) to require authentication for sensitive routes.
Troubleshooting
Site not loading?
# Check tunnel is running
sudo systemctl status cloudflared
# Check your app is running
curl localhost:80
# Check DNS propagation
dig myapp.com
"Address Not Found" on mobile?
DNS might not have propagated to your carrier yet. Try:
- Toggle airplane mode on/off
- Use a different DNS (1.1.1.1)
- Wait 15-30 minutes
502 Bad Gateway?
Your local app isn't responding. Check it's running on the correct port.
Cost
- Cloudflare Tunnel: Free
- Domain: ~$10/year
- Hosting: $0 (your own hardware)
When NOT to Use This
- High-traffic production apps (your home internet has limits)
- Apps requiring 99.99% uptime (your laptop can crash)
- Sensitive data without proper security measures
For serious production workloads, use proper cloud hosting.
Wrapping Up
Cloudflare Tunnel is perfect for:
- Side projects
- Development/staging environments
- Self-hosted apps
- Home automation dashboards
- Personal APIs
It took me about 15 minutes to go from "app running locally" to "app accessible worldwide with HTTPS."
No cloud bills. No DevOps complexity. Just your code, running on your hardware, accessible to the world.
Have questions? Drop a comment below or find me on Twitter/X.
Building something cool with this setup? I'd love to hear about it!
Tags: cloudflare, self-hosting, devops, tutorial, web-development
Top comments (0)