Workshop สำหรับเรียนรู้การใช้งาน Cloudflare Tunnel ตั้งแต่ Quick Tunnel, Named Tunnel, Custom Domain, Docker Compose ไปจนถึงแนวทางใช้งานจริงอย่างปลอดภัย

#1. Cloudflare Tunnel คืออะไร

Cloudflare Tunnel เป็นกลไกที่เชื่อม Web Application, REST API หรือบริการภายในเครือข่ายเข้ากับ Cloudflare ผ่านโปรแกรม cloudflared โดยฝั่งเซิร์ฟเวอร์เป็นผู้สร้างการเชื่อมต่อแบบ outbound ไปยัง Cloudflare

แนวคิดสำคัญคือเราไม่จำเป็นต้องเปิด inbound port 80/443 จาก Internet เข้าสู่ Origin Server โดยตรง และไม่จำเป็นต้องประกาศ Public IP ของ Origin ให้ผู้ใช้เข้าถึงโดยตรง

User / Browser
      |
      v
app.example.com
      |
      v
Cloudflare Edge
      |
      | Cloudflare Tunnel
      v
  cloudflared
      |
      v
localhost:8080
      |
      v
 Web / REST API

จึงเหมาะกับงาน เช่น

  • แชร์ Web Application ที่กำลังพัฒนา
  • เปิด Demo Application ให้ผู้ทดสอบ
  • Publish REST API จาก VM หรือเครื่องภายใน
  • Self-hosted Application
  • Home Lab
  • Development / Staging Environment
  • ระบบที่ไม่ต้องการเปิด Origin Server ให้ Internet เข้าถึงโดยตรง

#2. Cloudflare Tunnel กับการเปิด Port แบบเดิม

การเปิด Web Server แบบทั่วไปมักมีเส้นทางดังนี้

Internet
   |
Public IP
   |
Firewall
   |
Port 80 / 443
   |
Web Server

ขณะที่ Cloudflare Tunnel เปลี่ยนเป็น

Internet
   |
Cloudflare
   |
Encrypted Tunnel
   |
cloudflared
   |
Internal Service

ข้อดีเชิงสถาปัตยกรรมคือ Origin เป็นฝ่ายเชื่อมออกไปหา Cloudflare แทนการรอรับ connection จาก Internet โดยตรง

หมายเหตุ: Cloudflare Tunnel ช่วยลดการเปิดเผย Origin แต่ไม่ได้แทนที่การทำ Authentication, Authorization, Patch Management และการตั้งค่า Application Security ที่เหมาะสม


#3. สิ่งที่ต้องเตรียม

สำหรับ Quick Tunnel ต้องมีเพียง

  1. เครื่องที่ติดตั้ง cloudflared
  2. Web/API ที่กำลังทำงานอยู่

ตัวอย่างนี้สมมติ Application ทำงานที่

http://localhost:8080

สำหรับการใช้ hostname ของตนเองแบบ Named Tunnel ควรมี

  • Cloudflare Account
  • Domain ที่จัดการผ่าน Cloudflare
  • เครื่อง Server/VM ที่เชื่อมต่อ Internet ได้
  • cloudflared

#Workshop 1: Quick Tunnel

#4. ติดตั้ง cloudflared

ตรวจสอบก่อนว่าเครื่องมี cloudflared หรือไม่

cloudflared --version

#macOS

ติดตั้งด้วย Homebrew

brew install cloudflared

#Windows

สามารถติดตั้งผ่าน package manager ที่รองรับ หรือดาวน์โหลด cloudflared.exe จาก Cloudflare แล้วตรวจสอบด้วย

cloudflared.exe --version

#Linux

ใช้ package repository/package ของ Cloudflare ตาม distribution หรือดาวน์โหลด binary ที่เหมาะกับ architecture

ตรวจสอบหลังติดตั้ง

cloudflared --version

#5. สร้าง Web Server สำหรับทดลอง

ถ้ามี Python สามารถสร้าง HTTP Server ง่าย ๆ ได้

mkdir tunnel-demo
cd tunnel-demo

สร้าง index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Cloudflare Tunnel Demo</title>
</head>
<body>
    <h1>Hello Cloudflare Tunnel</h1>
    <p>My local server is online.</p>
</body>
</html>

เปิด Web Server

python -m http.server 8080

ทดสอบ

http://localhost:8080

#6. เปิด Quick Tunnel

เปิด Terminal อีกหน้าต่างแล้วรัน

cloudflared tunnel --url http://localhost:8080

ระบบจะแสดง URL ชั่วคราวลักษณะประมาณ

https://random-name.trycloudflare.com

นำ URL ไปเปิดจาก Browser หรืออุปกรณ์อื่นได้ทันที

Browser
   |
   v
trycloudflare.com
   |
   v
Cloudflare
   |
   v
cloudflared
   |
   v
localhost:8080

Quick Tunnel เหมาะกับ Development และ Testing มากกว่าระบบ Production เพราะ hostname เป็นแบบชั่วคราวและเปลี่ยนเมื่อสร้าง Tunnel ใหม่

หยุด Tunnel ด้วย

Ctrl + C

#7. Quick Tunnel สำหรับ REST API

สมมติ API ทำงานที่

http://localhost:8000

เปิด Tunnel

cloudflared tunnel --url http://localhost:8000

จากนั้นสามารถเรียก endpoint ผ่าน URL ที่ Cloudflare สร้างให้ เช่น

curl https://YOUR-TUNNEL.trycloudflare.com/api/users

แนวทางนี้มีประโยชน์สำหรับ

  • Mobile App Development
  • Webhook Testing
  • API Demo
  • Frontend/Backend ที่พัฒนาคนละเครื่อง
  • Integration Testing

#Workshop 2: Named Tunnel และ Custom Domain

#8. Login เข้า Cloudflare

cloudflared tunnel login

Browser จะเปิดหน้า Authentication ให้เลือก domain/zone ที่ต้องการอนุญาต

สำหรับ locally-managed tunnel กระบวนการนี้จะสร้างไฟล์ certificate สำหรับการจัดการ Tunnel ผ่าน CLI


#9. สร้าง Named Tunnel

ตัวอย่างตั้งชื่อว่า

my-web-tunnel

รัน

cloudflared tunnel create my-web-tunnel

ตรวจสอบรายการ Tunnel

cloudflared tunnel list

ผลลัพธ์จะมี Tunnel UUID ซึ่งต้องใช้ใน configuration


#10. สร้าง config.yml

ตำแหน่งที่ใช้ทั่วไปบน Linux/macOS คือ

~/.cloudflared/config.yml

ตัวอย่างสำหรับ Web ที่ port 8080

tunnel: YOUR-TUNNEL-UUID
credentials-file: /home/YOUR_USER/.cloudflared/YOUR-TUNNEL-UUID.json

ingress:
  - hostname: app.example.com
    service: http://localhost:8080

  - service: http_status:404

เปลี่ยน

  • YOUR-TUNNEL-UUID
  • YOUR_USER
  • app.example.com

ให้ตรงกับระบบจริง

กฎสุดท้าย

- service: http_status:404

ทำหน้าที่เป็น catch-all rule สำหรับ request ที่ไม่ตรงกับ ingress ก่อนหน้า


#11. เชื่อม DNS เข้ากับ Tunnel

รัน

cloudflared tunnel route dns my-web-tunnel app.example.com

Cloudflare จะสร้าง DNS route ให้ hostname เชื่อมไปยัง Tunnel

จากนั้นเริ่ม Tunnel

cloudflared tunnel run my-web-tunnel

ทดสอบ

https://app.example.com

ตรวจสอบข้อมูล Tunnel ได้ด้วย

cloudflared tunnel info my-web-tunnel

#Workshop 3: หลาย Application ใน Tunnel เดียว

Cloudflare Tunnel สามารถ route hostname หลายตัวไปยังหลาย service ได้

tunnel: YOUR-TUNNEL-UUID
credentials-file: /home/user/.cloudflared/YOUR-TUNNEL-UUID.json

ingress:
  - hostname: web.example.com
    service: http://localhost:3000

  - hostname: api.example.com
    service: http://localhost:8000

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

  - service: http_status:404

สถาปัตยกรรมจะเป็น

web.example.com --------> localhost:3000
                           ^
api.example.com --------> localhost:8000
                           ^
grafana.example.com ----> localhost:3001
           \               /
            \             /
             Cloudflare Tunnel

สร้าง DNS route ให้แต่ละ hostname

cloudflared tunnel route dns my-web-tunnel web.example.com
cloudflared tunnel route dns my-web-tunnel api.example.com
cloudflared tunnel route dns my-web-tunnel grafana.example.com

#Workshop 4: Docker Compose + Cloudflare Tunnel

#12. โครงสร้าง Project

cloudflare-demo/
├── docker-compose.yml
└── html/
    └── index.html

สร้าง html/index.html

<h1>Cloudflare Tunnel + Docker Compose</h1>
<p>Hello from NGINX container</p>

สร้าง docker-compose.yml

services:
  web:
    image: nginx:alpine
    restart: unless-stopped
    volumes:
      - ./html:/usr/share/nginx/html:ro

  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}
    depends_on:
      - web

สร้าง .env

TUNNEL_TOKEN=YOUR_TUNNEL_TOKEN

อย่า commit .env หรือ Tunnel Token ขึ้น Git repository

เพิ่มใน .gitignore

.env

ใน Cloudflare Dashboard กำหนด Published Application ให้ service ปลายทางเป็น

http://web:80

เพราะ cloudflared และ web อยู่ใน Docker network เดียวกัน

เริ่มระบบ

docker compose up -d

ตรวจสอบ

docker compose ps

ดู log

docker compose logs -f cloudflared

สถาปัตยกรรม

Internet
   |
   v
Cloudflare Edge
   |
   v
Cloudflare Tunnel
   |
   v
cloudflared container
   |
   | Docker Network
   v
NGINX container :80

ข้อสังเกตสำคัญคือไม่จำเป็นต้องใส่

ports:
  - "80:80"

ให้กับ NGINX หากต้องการให้ Web เข้าถึงผ่าน Tunnel เท่านั้น เพราะ cloudflared ติดต่อ container web ผ่าน Docker network ได้โดยตรง


#Workshop 5: Cloudflare Tunnel + Traefik

อีกแนวทางคือใช้ Traefik เป็น Reverse Proxy ภายใน

Internet
   |
Cloudflare
   |
Cloudflare Tunnel
   |
cloudflared
   |
Traefik
   |
   +----------+----------+
   |          |          |
 Web        REST API   Grafana

Cloudflare Tunnel ทำหน้าที่นำ traffic เข้าสู่ private infrastructure ส่วน Traefik รับผิดชอบ routing ภายในไปยัง services ต่าง ๆ

แนวทางนี้เหมาะกับ

  • Docker Host ที่มีหลาย Application
  • Home Lab
  • Development Server
  • Internal Platform
  • Microservices Lab

#13. รัน cloudflared เป็น Service บน Linux

สำหรับ locally-managed tunnel ที่มี config.yml สามารถติดตั้งให้ทำงานเป็น system service

sudo cloudflared --config /home/YOUR_USER/.cloudflared/config.yml service install

เริ่ม service

sudo systemctl start cloudflared

ตรวจสอบ

sudo systemctl status cloudflared

restart หลังแก้ configuration

sudo systemctl restart cloudflared

วิธีนี้เหมาะกว่าเปิด Terminal ค้างไว้บน Server เพราะ service สามารถเริ่มพร้อมระบบได้


#14. Security Best Practices

Cloudflare Tunnel ลดความจำเป็นในการ expose Origin แต่ควรออกแบบ security หลายชั้น

#14.1 อย่าเปิด Origin Port โดยไม่จำเป็น

หาก Application ต้องเข้าผ่าน Tunnel เท่านั้น ไม่ควรเปิด port ของ Application ต่อ Internet โดยตรง

#14.2 ปกป้อง Tunnel Token

Tunnel Token ควรถูกจัดการในลักษณะ secret เช่น

Environment Variable
Secret Manager
Docker Secret
Kubernetes Secret
CI/CD Secret

ไม่ควรเขียน token ลง source code หรือ commit ลง Git

#14.3 ใช้ Cloudflare Access กับระบบภายใน

ระบบเช่น

admin.example.com
grafana.example.com
jenkins.example.com
internal.example.com

ไม่ควรเปิดเป็น public application โดยไม่มี authentication

สามารถใช้ Cloudflare Access/Zero Trust เพิ่ม identity-aware access policy ก่อน request เดินทางถึง Application

#14.4 Application ยังต้องมี Security ของตัวเอง

Cloudflare Tunnel ไม่ได้ทำให้ช่องโหว่ใน Application หายไป จึงยังต้องคำนึงถึง

  • Authentication
  • Authorization
  • Input Validation
  • Dependency Updates
  • API Security
  • Secret Management
  • Logging และ Monitoring

#14.5 Production ควรออกแบบ High Availability

ระบบสำคัญไม่ควรพึ่ง cloudflared process หรือ host เพียงตัวเดียว ควรพิจารณา replicas/connectors หลาย instance เพื่อเพิ่ม availability


#15. Troubleshooting

#Tunnel เปิดได้ แต่ Web เข้าไม่ได้

ตรวจสอบว่า Application ทำงานจริงหรือไม่

curl http://localhost:8080

จากนั้นตรวจสอบ Tunnel

cloudflared tunnel list
cloudflared tunnel info my-web-tunnel

#Docker ติดต่อ Application ไม่ได้

หาก cloudflared อยู่ใน container อย่าใช้

localhost:8080

เพื่ออ้างถึง container อื่น เพราะ localhost จะหมายถึง container ของ cloudflared เอง

ให้ใช้ Docker service name เช่น

http://web:80

#DNS ยังเข้าไม่ได้

ตรวจสอบ route และ hostname

cloudflared tunnel route dns my-web-tunnel app.example.com

รวมถึงตรวจสอบ DNS record ใน Cloudflare Dashboard

#Server อยู่หลัง Firewall เข้มงวด

ตรวจสอบ outbound connectivity จากเครื่องที่รัน cloudflared ไปยัง Cloudflare โดยเฉพาะข้อกำหนด network/port ตามเอกสาร Cloudflare Tunnel เวอร์ชันปัจจุบัน


#16. คำสั่งที่ใช้บ่อย

# ตรวจสอบ version
cloudflared --version

# Quick Tunnel
cloudflared tunnel --url http://localhost:8080

# Login
cloudflared tunnel login

# สร้าง Tunnel
cloudflared tunnel create my-web-tunnel

# ดู Tunnel
cloudflared tunnel list

# ดูรายละเอียด
cloudflared tunnel info my-web-tunnel

# สร้าง DNS route
cloudflared tunnel route dns my-web-tunnel app.example.com

# รัน Tunnel
cloudflared tunnel run my-web-tunnel

# Docker Compose
docker compose up -d

# ดู log
docker compose logs -f cloudflared

#17. แบบฝึกหัด

#Lab 1 --- Quick Tunnel

สร้าง Web Server ที่ port 8080 และเปิดให้ Internet เข้าถึงผ่าน Quick Tunnel

เป้าหมาย

localhost:8080
      |
      v
Cloudflare Tunnel
      |
      v
trycloudflare.com

#Lab 2 --- Custom Domain

สร้าง Named Tunnel และกำหนด

web.example.com

ให้ route ไปยัง

localhost:8080

#Lab 3 --- Multi-Service

กำหนด

web.example.com      -> localhost:3000
api.example.com      -> localhost:8000
grafana.example.com  -> localhost:3001

ผ่าน Tunnel เดียว

#Lab 4 --- Docker

สร้าง NGINX และ cloudflared ด้วย Docker Compose โดยไม่ publish port ของ NGINX ออกสู่ Host

#Challenge --- Zero Trust

เพิ่ม Access Policy หน้า Internal Application เพื่อให้เฉพาะผู้ใช้ที่ได้รับอนุญาตจึงเข้าถึงได้


#18. สรุป

Cloudflare Tunnel เป็นแนวทางที่เหมาะสำหรับการ publish Application จาก Local Server, VM, Docker หรือ private infrastructure โดยไม่ต้องเปิด inbound port ของ Origin สู่ Internet โดยตรง

เส้นทางการเรียนรู้ที่แนะนำคือ

Quick Tunnel
     |
     v
Named Tunnel
     |
     v
Custom Domain
     |
     v
Multiple Services
     |
     v
Docker Compose
     |
     v
Cloudflare Access
     |
     v
High Availability

สำหรับ Development สามารถเริ่มจาก Quick Tunnel ได้ภายในไม่กี่คำสั่ง ส่วน Production ควรใช้ Named/managed Tunnel, stable hostname, secret management, access control, monitoring และ redundancy ให้เหมาะสมกับระดับความสำคัญของระบบ


#เอกสารอ้างอิง

ตรวจสอบเอกสาร Cloudflare รุ่นปัจจุบันก่อนนำ configuration ไปใช้กับ Production เนื่องจาก CLI, Dashboard และคุณสมบัติของบริการสามารถเปลี่ยนแปลงได้