Setting Up Cloudflare Tunnel

June 28, 2026 Ravi Kumar Gupta 10 min read
cloudflarecloudflare tunnelself-hosted applicationssecure accessreverse proxynginxtraefikhome server

I recently got to learn about cloudflare tunnel and I wanted to know more about it. From what I experienced while setting it up, I am amazed at what it can do and how easy it is to setup.

No port forwarding. No public IP. No reverse proxy. Automatic HTTPS.

And the best part is that it is free for personal use.

Architecture#

My setup consists of the following:

  • Domain registered with GoDaddy
  • Existing website hosted on another provider
  • Cloudflare managing DNS
  • Rocky Linux home server
  • Local application running on port 7374

This local app is actually a vite development server running on my home server. I wanted to expose it to the Internet without exposing my home network directly.

Internet
     │
Cloudflare DNS
     │
Cloudflare Tunnel
     │
Home Server
     │
127.0.0.1:7374

The application never becomes directly accessible from the Internet. Instead, the server establishes an outbound encrypted connection to Cloudflare.

Cloudflare becomes the public entry point.

Step 1: Move DNS to Cloudflare#

My domain was already registered with GoDaddy and hosted elsewhere.

Current setup:

Registrar : GoDaddy
DNS        : Existing Hosting Provider
Website    : Existing Hosting Provider

The website itself remains hosted exactly where it is.

Only DNS management moves to Cloudflare.

Add your domain#

  1. Create a free Cloudflare account.
  2. Click Add Domain.
  3. Enter your domain.
  4. Select the Free plan.

Cloudflare automatically imports existing DNS records.

Verify all records carefully before proceeding.

Pay particular attention to:

  • A records
  • CNAME records
  • MX records
  • TXT records
  • SPF
  • DKIM

Keep the following records as DNS Only instead of Proxied.

mail
webmail
ftp
cpanel
cpcontacts
cpcalendars
webdisk
whm
autodiscover

Your website records can remain Proxied.

Change Nameservers#

Cloudflare provides two nameservers similar to:

venus.ns.cloudflare.com
jihoon.ns.cloudflare.com

Login to your domain registrar and replace the existing nameservers with the ones provided by Cloudflare.

Wait for propagation.

Verify using:

whois example.com | grep "Name Server"

and

dig NS example.com

Once Cloudflare becomes Active, the migration is complete.

Step 2: Install cloudflared#

On Rocky Linux:

curl -fsSL https://pkg.cloudflare.com/cloudflared.repo \
| sudo tee /etc/yum.repos.d/cloudflared.repo

sudo dnf install cloudflared

Verify installation.

cloudflared --version

Step 3: Authenticate#

cloudflared tunnel login

A browser window opens.

Authorize the server.

A certificate is downloaded.

~/.cloudflared/cert.pem

This machine can now manage Cloudflare tunnels.

Step 4: Create a Tunnel#

I prefer creating one tunnel per machine.

For example:

lab1
lab2
mac
rpi
windows

Instead of generic names.

Create the tunnel.

cloudflared tunnel create lab1

This creates:

~/.cloudflared/<tunnel-id>.json

Keep this file safe.

Step 5: Create a DNS Route#

Expose a subdomain.

For example:

cloudflared tunnel route dns lab1 app.example.com

Cloudflare automatically creates the required DNS record.

Step 6: Configure the Tunnel#

Create:

/etc/cloudflared/config.yml

Example:

tunnel: lab1
credentials-file: /home/ravi/.cloudflared/<tunnel-id>.json

ingress:
  - hostname: app.example.com
    service: http://127.0.0.1:7374

  - service: http_status:404

Additional applications are simply more entries.

ingress:
  - hostname: app.example.com
    service: http://127.0.0.1:7374

  - hostname: grafana.example.com
    service: http://127.0.0.1:3001

  - hostname: sonar.example.com
    service: http://127.0.0.1:9000

  - hostname: mav.example.com
    service: http://127.0.0.1:3000

  - service: http_status:404

Step 7: Test the Tunnel#

Before creating a service, run manually.

cloudflared tunnel --config /etc/cloudflared/config.yml run lab1

You should see messages similar to:

Registered tunnel connection

Verify your application locally.

curl http://127.0.0.1:7374

Then access:

https://app.example.com

Step 8: Install as a System Service#

Once everything works:

sudo cloudflared service install

sudo systemctl enable cloudflared

sudo systemctl start cloudflared

Verify:

systemctl status cloudflared

The tunnel will now survive server reboots.

Vite Users#

A small section for only Vite users. If you are exposing a Vite development server, you may encounter:

Blocked request.
This host ("app.example.com") is not allowed.

Vite protects against DNS rebinding attacks.

Add your hostname to vite.config.ts.

export default defineConfig({
  server: {
    host: '0.0.0.0',
    port: 7374,

    allowedHosts: [
      'app.example.com'
    ]
  }
})

Or during development:

allowedHosts: true

Restart the Vite server. It should now work.

How easy is that.

Cloudflare Tunnel is only the beginning. Cloudflare Zero Trust can be used to protect internal applications by requiring authentication before users can access them.

For example:

https://grafana.example.com

Instead of exposing Grafana publicly, Cloudflare can require:

  • Google Login
  • GitHub Login
  • Microsoft Login
  • One Time PIN
  • Multi Factor Authentication
  • Specific Email Addresses

This means my internal infrastructure remains private while still being accessible securely from anywhere in the world. For homelabs, development environments and self hosted applications, this is one of the cleanest ways to publish services without exposing the network directly to the Internet.

This is what I might explore next when the dopamine hits again ;)