ตั้งค่า Varnish Cache หน้า WordPress บน Cloud VPS

Varnish Cache คืออะไร

Varnish Cache เป็น HTTP Accelerator หรือ Reverse Proxy Cache ที่ทำงานอยู่หน้า Web Server (Nginx/Apache) หน้าที่หลักคือเก็บหน้าเว็บที่เข้าชมบ่อยๆ ไว้ในหน่วยความจำ (RAM) เมื่อผู้ใช้เข้าชมหน้าเดิม Varnish จะส่งหน้าที่ Cache ไว้ทันที โดยไม่ต้องประมวลผล PHP หรือ Query Database เลย ทำให้เว็บโหลดเร็วมากและหลดของ Server ลดลงอย่างมาก Varnish ได้รับความนิยมจาก Twitter, Facebook, Wikipedia เพราะสามารถทำให้เว็บเร็วขึ้น 10-100 เท่าได้

ข้อดีและข้อเสียของ Varnish Cache

ข้อดี:

  • เร็วสุดสุด – ส่งหน้าเว็บจาก RAM โดยไม่ต้องประมวลผล
  • ลดทรัพยากร Server – CPU และ RAM ของ Web Server ลดลงอย่างมาก
  • รองรับ Traffic สูง – สามารถรองรับ User พร้อมกันได้หลายพันคน
  • เหมาะสำหรับ Content Heavy Site – เว็บบล็อก ข่าว ร้านค้าออนไลน์
  • ตั้งค่าได้ยืดหยุ่น – ผ่าน VCL (Varnish Configuration Language)

ข้อเสีย:

  • ตั้งค่าซับซ้อน – ต้องเข้าใจ Server Administration และ HTTP Protocol
  • ต้องมี RAM พอ – Cache ขนาดใหญ่ต้องใช้ RAM มาก
  • ไม่เหมาะสำหรับ Dynamic Content – เช่น WooCommerce หรือเว็บที่ข้อมูลเปลี่ยนบ่อยๆ
  • ต้องจัดการ Cache Invalidation – เมื่ออัปเดต WordPress ต้องล้าง Cache ให้ถูกต้อง
  • ไม่รองรับ HTTPS โดยตรง – ต้องใช้ Nginx เป็น Reverse Proxy หน้า Varnish
  • ต้องมีพนักงาน IT ดูแล – หากมีปัญหาต้องให้คนรู้เรื่องแก้ไข

โครงสร้างการทำงานของ Varnish

โครงสร้างแบบแนะนำสำหรับ WordPress บน Cloud VPS:

ผู้เยี่ยมชม (Browser)
    ↓
Nginx SSL Termination (Port 443 HTTPS)
    ↓
Varnish Cache (Port 8080)
    ↓
Nginx Web Server (Port 8081)
    ↓
PHP-FPM
    ↓
MySQL/MariaDB

การไหลของข้อมูล:

  • User ส่ง Request มาผ่าน HTTPS ไปยัง Nginx Layer 1 ที่ Port 443
  • Nginx Layer 1 ทำการ SSL Termination (แปลง HTTPS เป็น HTTP) แล้วส่งต่อไป Varnish ที่ Port 8080
  • Varnish ตรวจสอบว่ามี Cache หรือไม่ หากมี จะส่ง Cache ทันที หากไม่มี จะส่งต่อไป Nginx Layer 2 ที่ Port 8081
  • Nginx Layer 2 ส่งต่อไป PHP-FPM เพื่อประมวลผล WordPress
  • PHP-FPM ทำการสร้างหน้าเว็บ Query Database หรืออื่นๆ แล้วส่งกลับไป
  • Varnish เก็บหน้าเว็บที่ได้มาลงใน Cache และส่งให้ User พร้อมกับตั้งค่า TTL (Time To Live)
  • ครั้งถัดไปที่ User เข้าชมหน้าเดิม Varnish จะส่ง Cache โดยไม่ต้องประมวลผล

ตรวจสอบความพร้อมก่อนติดตั้ง Varnish

ก่อนติดตั้ง Varnish บน Cloud VPS ของ de.co.th ต้องตรวจสอบ:

  • RAM เพียงพอ: ควรมี RAM อย่างน้อย 4GB ทั่วไปขึ้น (ทั่วไป 2GB สำหรับ Varnish, 2GB สำหรับ MySQL/PHP)
  • Nginx ทำงาน: Varnish ต้อง Reverse Proxy ไปยัง Nginx ดังนั้น Nginx ต้องทำงานอยู่แล้ว
  • WordPress ติดตั้งแล้ว: มี WordPress ที่ใช้งาน ไม่ใช่ Staging
  • Domain ใช้ SSL: ควรมี SSL Certificate ใช้แล้ว (Let’s Encrypt)
  • Backup Data: สำรองข้อมูล WordPress และ Database ก่อนทำการเปลี่ยนแปลง

ขั้นตอนการติดตั้ง Varnish บน Cloud VPS

ขั้นตอนที่ 1: ติดตั้ง Varnish Package

# อัปเดต Package List
sudo apt update

# ติดตั้ง Varnish
sudo apt install varnish -y

# ตรวจสอบเวอร์ชัน
varnishd -version

ขั้นตอนที่ 2: เปลี่ยน Port ของ Nginx

เนื่องจาก Varnish จะใช้ Port 80 (HTTP) ต้องเปลี่ยน Nginx ให้ใช้ Port 8080:

# แก้ไข Nginx Configuration
sudo nano /etc/nginx/sites-available/default

# หาบรรทัด listen 80; และเปลี่ยนเป็น:
listen 8080;

# หรือถ้าใช้ Nginx Default VirtualHost
sudo nano /etc/nginx/nginx.conf

# หาบรรทัด listen 80 default_server; เปลี่ยนเป็น:
listen 8080 default_server;

บันทึก (Ctrl+X, Y, Enter) แล้ว Restart Nginx:

# ทดสอบ Configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx

# ตรวจสอบว่า Nginx ฟังที่ Port 8080
sudo netstat -tlnp | grep nginx

ขั้นตอนที่ 3: สร้าง Varnish Configuration (VCL)

สร้างไฟล์ VCL ที่เหมาะสำหรับ WordPress:

sudo nano /etc/varnish/default.vcl

ลบเนื้อหาเดิมทั้งหมด และใส่ Configuration นี้:

vcl 4.0;

# กำหนด Backend (Nginx)
backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .connect_timeout = 10s;
    .first_byte_timeout = 30s;
    .between_bytes_timeout = 5s;
}

# Subroutine VCL_RECV - เมื่อ Request เข้ามา
sub vcl_recv {
    # ไม่ Cache Admin Pages
    if (req.url ~ "^/wp-admin" || req.url ~ "^/wp-login" || req.url ~ "^/wp-json") {
        return (pass);
    }
    
    # ไม่ Cache Logged-in Users
    if (req.http.cookie ~ "wordpress_logged_in") {
        return (pass);
    }
    
    # ไม่ Cache POST Requests
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }
    
    # ไม่ Cache ถ้า URL มี Query String (อย่างไรก็ตาม)
    if (req.url ~ "\\?(.*)$") {
        # ยกเว้น บาง Query String
        if (req.url ~ "utm_source|utm_medium|utm_campaign") {
            return (hash);
        }
        return (pass);
    }
    
    # ล้าง Cookie ที่ไม่จำเป็น
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-\\d+=[^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-\\d+=[^;]*", "");
    
    # สรุป: Cache ส่วนอื่นๆ
    return (hash);
}

# Subroutine VCL_BACKEND_RESPONSE - เมื่อ Response จาก Backend มา
sub vcl_backend_response {
    # ตั้ง TTL (Time To Live) - เก็บ Cache นานแค่ไหน
    set beresp.ttl = 1h;  # 1 ชั่วโมง
    
    # สำหรับ Static Content ให้ Cache นาน
    if (bereq.url ~ "\\.(jpg|jpeg|png|gif|css|js|pdf|txt|ico|woff|woff2|ttf)") {
        set beresp.ttl = 30d;  # 30 วัน
    }
    
    # ไม่ Cache เมื่อ Status Error
    if (beresp.status == 404 || beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
        set beresp.ttl = 10m;  # เก็บแค่ 10 นาที
    }
}

# Subroutine VCL_DELIVER - เตรียมส่ง Response ให้ User
sub vcl_deliver {
    # เพิ่ม Debug Header เพื่อดู Cache Status
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT " + obj.hits;
    } else {
        set resp.http.X-Cache = "MISS";
    }
    
    # เพิ่มชื่อ Varnish Version
    set resp.http.X-Cache-Server = "Varnish/" + server.version;
}

บันทึก (Ctrl+X, Y, Enter)

ขั้นตอนที่ 4: ตั้งค่า Port ของ Varnish

# แก้ไข Varnish Systemd Service
sudo nano /etc/systemd/system/varnish.service

# หาบรรทัด ExecStart และเปลี่ยน Port เป็น 80:
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :80 -T localhost:6082 -b localhost:8080 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m

# -a :80 = ฟังที่ Port 80
# -b localhost:8080 = Backend คือ localhost ที่ Port 8080 (Nginx)
# -s malloc,256m = ใช้ RAM 256MB สำหรับ Cache

บันทึกแล้ว reload systemd:

sudo systemctl daemon-reload

ขั้นตอนที่ 5: เริ่มต้น Varnish Service

# เริ่มต้น Varnish
sudo systemctl start varnish

# ตั้งค่า Autostart
sudo systemctl enable varnish

# ตรวจสอบสถานะ
sudo systemctl status varnish

# ตรวจสอบ Port ที่ Varnish ฟัง
sudo netstat -tlnp | grep -E 'varnish|80|8080'

ทดสอบว่า Varnish ทำงานหรือไม่

# ทดสอบ Cache Hit
curl -I http://your-domain.com/

# ตรวจสอบ Header ที่ส่งกลับมา ควรเห็น:
# X-Cache: HIT 1
# หรือ X-Cache: MISS ครั้งแรก

# ดูรายละเอียด Varnish Stats
varnishstat

# ดูเรียลไทม์ของการ Cache
varnishlog

ติดตั้ง WordPress Plugin สำหรับ Varnish

เพื่อให้ WordPress สามารถล้าง (Purge) Cache อัตโนมัติเมื่อมีการอัปเดตเนื้อหา ติดตั้ง Plugin:

# หรือ ไปยังวัสดุ Plugins > Add New ค้นหา "Varnish HTTP Purge"
wp plugin install varnish-http-purge --activate

Plugin นี้จะส่ง PURGE Request ไปยัง Varnish ทันทีเมื่อ:

  • สร้าง Post หรือ Page ใหม่
  • แก้ไข Post หรือ Page
  • ลบ Post หรือ Page
  • สิ่งพิมพ์มี Comment ใหม่
  • เปลี่ยน Theme Settings

การตรวจสอบและแก้ไขปัญหาทั่วไป

ปัญหา: WordPress ไม่อัปเดตบน Frontend

สาเหตุ: Varnish ยังคงเสิร์ฟ Cached Version เก่า

วิธีแก้:

# ล้าง Cache ทั้งหมด
sudo varnishadm ban req.url ~ ".*"

# หรือล้าง Cache เฉพาะหน้านั้น
sudo varnishadm ban "req.url == /page-slug"

# ตรวจสอบ Ban Rules
sudo varnishadm ban.list

ปัญหา: Varnish ไม่เก็บ Cache

สาเหตุ: VCL Configuration ไม่ถูกต้อง หรือ Backend ไม่ตอบสนอง

วิธีแก้:

# ตรวจสอบว่า Nginx ทำงานหรือไม่
sudo systemctl status nginx

# ตรวจสอบ Nginx Error Log
sudo tail -f /var/log/nginx/error.log

# ทดสอบการเชื่อมต่อ Nginx โดยตรง
curl -H "Host: your-domain.com" http://127.0.0.1:8080/

# ทดสอบ Varnish Configuration
sudo varnishd -f /etc/varnish/default.vcl -d

ปัญหา: Error “Backend Fetch Failed”

สาเหตุ: Nginx ไม่ฟังที่ Port 8080 หรือไฟร์วอล์ลปิด Port

วิธีแก้:

# ตรวจสอบ Port ที่ Nginx ฟัง
sudo netstat -tlnp | grep nginx

# ถ้าไม่ใช่ Port 8080 ให้แก้ไข Nginx Config อีกครั้ง
sudo nano /etc/nginx/sites-available/default

# ตรวจสอบ Firewall (UFW)
sudo ufw allow 8080

# Restart Nginx
sudo systemctl restart nginx

การ Optimize Varnish เพื่อประสิทธิภาพดีขึ้น

เมื่อ Varnish ทำงานแล้ว สามารถ Optimize ได้:

  • เพิ่มขนาด Cache Memory: แก้ไข “-s malloc,256m” เป็น “-s malloc,512m” หรือมากกว่า ขึ้นอยู่กับ RAM
  • ปรับ TTL ตามเนื้อหา: Post ให้ TTL นาน Comments ให้ TTL สั้น
  • บีม Compression: เพิ่ม “set beresp.do_gzip = true;” ใน VCL เพื่อบีม Gzip
  • Cache Warming: สร้าง Cron Job เพื่อเข้าชม URL สำคัญเพื่อ Pre-cache
  • Monitor Memory Usage: ใช้ “free -h” และ “varnishstat” เพื่อตรวจสอบ RAM

ข้อควรระวังและ Best Practices

  • ไม่เหมาะสำหรับ WooCommerce: หากใช้ WooCommerce ตั้งค่าให้ไม่ Cache Product Pages และ Cart
  • ระมัดระวัง HTTPS: Varnish ไม่รองรับ HTTPS โดยตรง ต้องใช้ Reverse Proxy หน้า (เช่น Nginx หรือ Cloudflare)
  • ล้าง Cache ก่อนอัปเดต: ก่อนอัปเดต Plugin หรือ Theme ให้ล้าง Cache ก่อน
  • ตรวจสอบ Logs เป็นประจำ: ดู Varnish Logs เพื่อตรวจสอบว่า Cache Hit Rate ดีหรือไม่
  • ไม่เก็บ Sensitive Data: ไม่ใส่ Password หรือข้อมูลส่วนตัวใน URL หรือ GET Parameters

ทางเลือกอื่นแทน Varnish

หากพบว่า Varnish ซับซ้อนเกินไป มีทางเลือกอื่น:

  • Nginx FastCGI Cache: ตั้งค่าง่ายกว่า แต่ลดประสิทธิภาพไม่เท่า Varnish
  • Redis Cache: เหมาะสำหรับ Object Caching ของ WordPress
  • Cloudflare: CDN บน Cloud ปกป้อง DDoS และ Cache พร้อมกัน
  • WP Super Cache Plugin: Plugin Cache ฟรีสำหรับ WordPress ผู้เริ่มต้น
  • W3 Total Cache: Plugin ครบครันรองรับหลาย Cache Layers

สรุป

Varnish Cache เป็นตัวเลือกที่ยอดเยี่ยมสำหรับเว็บ WordPress ที่มี Traffic สูงมากบน Cloud VPS ของ de.co.th หากตั้งค่าอย่างถูกต้อง สามารถเพิ่มความเร็ว 10-100 เท่า และลดทรัพยากร Server ได้อย่างมาก อย่างไรก็ตาม ต้องให้ความสนใจเรื่องการตั้งค่า Cache Invalidation และการตรวจสอบผลงาน สำหรับผู้เริ่มต้น อาจจะเริ่มจาก Nginx FastCGI Cache หรือ Plugin Cache ง่ายๆ ก่อน และเมื่อได้ประสบการณ์ก็ค่อยอัพเกรดเป็น Varnish ได้ ทีมสนับสนุน de.co.th มีความสามารถสูงและพร้อมช่วยตั้งค่า Varnish 24/7 หากคุณต้องการการช่วยเหลือเพิ่มเติม