Documents

Cloudflare Tunnel Subdomain Serving: Advanced Guide (Part 2)

5 min readMar 24, 2026Mar 24, 2026

[Chapter 2] Serving Subdomains with Cloudflare


Let's walk through this with some concrete examples.
Here's the home lab setup used throughout:

Example environment:

  • hr106 → blog
  • hr107 → playground
  • hr109 → geny
  • Domain: hrletsgo.me

1. Overall Architecture

                Internet
                    │
              Cloudflare
                    │
      ┌───────┼────────┐
      │             │             │
   hr106          hr107         hr109
  (blog)      (playground)     (geny)
      │             │             │
 cloudflared   cloudflared   cloudflared
      │             │             │
   nginx         nginx         nginx
      │             │             │
 frontend/backend services (docker)

Key characteristics:

  • Each server runs its own independent tunnel
  • No external port forwarding
  • All traffic routed through Cloudflare

2. Why This Architecture Works

Traditional approach

인터넷 → 공유기 → 서버

Problems:

  • Exposed ports
  • Exposed IP
  • Larger attack surface

Tunnel approach

서버 → Cloudflare (outbound)

Benefits:

  • No inbound ports
  • Server IP is hidden
  • DDoS / WAF protection

3. Per-Server Tunnel Strategy

  • One tunnel per server

Example:

hr106 → hr106 tunnel → hrletsgo.me
hr107 → hr107 tunnel → playground.hrletsgo.me
hr109 → hr109 tunnel → geny.hrletsgo.me

This approach offers:

  • Easier debugging
  • Fault isolation
  • Simpler operations

4. nginx + Docker Layout

Recommended structure for each server:

cloudflared
    ↓
nginx (reverse proxy)
    ↓
docker services

Example port assignments:

  • backend: 8000
  • frontend: 3000
  • nginx: 80
  • host: 58443 → 80

5. HTTP vs HTTPS Design

Principle

  • External: HTTPS (Cloudflare)
  • Internal: HTTP (localhost)

Rationale

Cloudflare → cloudflared → localhost

This path is:

  • On the same server
  • Not exposed externally

HTTP is sufficient here.


6. When to Use an HTTPS Origin

Use HTTPS when the target is not localhost:

  • cloudflared → a different server
  • cloudflared → NAS
  • cloudflared → VM

Apply this to any sensitive service:

  • admin panels
  • AI servers
  • internal APIs

Flow:

사용자 → 로그인 → Cloudflare → 서버

Supported identity providers:

  • Google login
  • GitHub login
  • OTP

8. SSH Tunnel

Eliminates the need for port forwarding entirely.

ssh → Cloudflare → tunnel → 서버

Benefits:

  • Port 22 can be closed
  • Blocks external attacks

9. Operational Tips

1. Check running services

docker ps
ss -tlnp

2. Determine HTTP vs HTTPS

curl http://localhost:포트
curl -vk https://localhost:포트

3. Check logs

journalctl -u cloudflared -f

10. Common Failure Types

502 Bad Gateway

  • Origin is down
  • Wrong port

1033

  • Tunnel is not running

TLS error

  • Connecting via HTTPS to an HTTP-only origin

11. Scaling Patterns

Option 1: Per-server tunnels

  • Simple
  • Recommended

Option 2: Centralized reverse proxy

Cloudflare → 1 tunnel → nginx → 여러 서비스
  • Easier to manage centrally
  • Adds complexity

  • One tunnel per server
  • Single nginx entry point
  • Use Docker internal networks
  • Remove all external port forwarding
  • Apply Cloudflare Access

13. Real-World Configuration Examples

blog

hrletsgo.me → hr106 → nginx → blog

playground

playground.hrletsgo.me → hr107 → nginx → app

geny

geny.hrletsgo.me → hr109 → nginx → AI agent

14. Key Takeaways

  • Tunnel = outbound connection
  • No port forwarding needed
  • HTTP to localhost is safe
  • DNS resolves through the tunnel
  • Use systemd to keep it always running