ตั้งค่า Nginx Reverse Proxy สำหรับ WebSocket ไม่ให้ Connection หลุด
ทำความเข้าใจ Upgrade header, Connection header, timeout และ proxy configuration ที่จำเป็นเมื่อให้ Nginx ส่งต่อ WebSocket ไปยัง backend แบบ real-time

ภาพรวม
Nginx ใช้กับ WebSocket ได้ดีมาก แต่ถ้าไม่เพิ่มค่าบางอย่าง จะเจออาการต่อไม่ติด ต่อได้แป๊บเดียวแล้วหลุด หรือรับ real-time ไม่ต่อเนื่อง ⚙️🌐🚀
จุดสำคัญอยู่ที่ WebSocket ไม่ได้ทำงานเหมือน HTTP ปกติ ตอนเริ่มต้นจะใช้ HTTP request แล้วขออัปเกรดการเชื่อมต่อเป็น WebSocket ถ้า Nginx ไม่ส่ง header สำหรับ upgrade ต่อไปยัง backend การเชื่อมต่อจะพังทันที 🔌
ค่าที่มักต้องเพิ่มใน Nginx มีอยู่ไม่กี่จุด แต่สำคัญมาก 🛠️
ตัวอย่างแนวทางตั้งค่า
server { listen 80; server_name yourdomain.com;
location /socket/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
}
}
แต่ละบรรทัดมีผลต่างกันพอสมควร ✨
proxy_http_version 1.1 จำเป็นเพราะ WebSocket upgrade ต้องใช้ HTTP/1.1 ถ้ายังปล่อยค่าเดิมบางระบบจะ upgrade ไม่ผ่าน
proxy_set_header Upgrade $http_upgrade ส่ง header Upgrade จาก client ไปยัง backend ถ้าไม่มี บริการฝั่งแอปจะไม่รู้ว่าต้องเปลี่ยนโปรโตคอล
proxy_set_header Connection "upgrade" บอกให้เชื่อมต่อแบบอัปเกรด เป็นอีกบรรทัดที่มักลืมกันบ่อย 😅
proxy_read_timeout 3600 ช่วยให้ connection ที่เปิดค้างสำหรับงาน real-time ไม่โดนตัดเร็วเกินไป เหมาะกับ chat, live dashboard, notification, multiplayer system ⏱️💬📡
proxy_send_timeout 3600 ป้องกันฝั่งส่งข้อมูลโดน timeout เร็วเกิน โดยเฉพาะระบบที่มีการส่งเป็นช่วงๆ ไม่ได้ยิงถี่ตลอดเวลา
ถ้าใช้งานผ่าน path เฉพาะ เช่น /ws หรือ /socket ควรให้ route ฝั่ง backend ตรงกันด้วย บางปัญหาไม่ได้มาจาก Nginx แต่มาจาก path mismatch ระหว่าง frontend กับ backend 🧩
อีกจุดที่หลายคนไม่รู้ ถ้ามี CDN, Load Balancer หรือ Reverse Proxy ซ้อนอีกชั้น ต้องเช็กทุกชั้นว่ารองรับ WebSocket เพราะบางที Nginx ตั้งถูกหมดแล้ว แต่โดนตัดก่อนถึงแอปจริง ☁️
กรณีใช้ HTTPS WebSocket จะกลายเป็น wss:// ต้องแน่ใจว่า SSL terminate ถูกชั้น และส่งต่อไป backend ได้ตามโครงสร้างที่ออกแบบไว้ 🔒
เทคนิคที่ช่วยลดปัญหาในระบบจริง เปิด access log และ error log สำหรับ location ที่ใช้ WebSocket แยกไว้ เวลาหาสาเหตุจะเร็วมาก โดยเฉพาะตอนเจอ 400, 426, 502 หรืออาการ upgrade ไม่สำเร็จ 📋
ถ้า backend เป็น Node.js, FastAPI, Socket.IO, Django Channels หรือ Go หลักการฝั่ง Nginx แทบเหมือนกัน ต่างกันแค่ path และพอร์ตของ upstream
บางระบบควรเพิ่ม upstream block เพื่อให้จัดการ backend ง่ายขึ้น เช่น
upstream backend { server 127.0.0.1:3000; }
แล้วค่อย proxy_pass http://backend; แบบนี้เวลาเปลี่ยนปลายทางจะดูแลง่ายกว่า 🧠
เรื่องที่คนชอบพลาดอีกอย่าง อย่าทดสอบเฉพาะหน้าเว็บที่โหลดได้ เพราะหน้าเว็บปกติอาจเปิดได้ แต่ WebSocket fail อยู่เงียบๆ ควรเปิด DevTools แล้วดู Network ว่าสถานะ upgrade สำเร็จหรือไม่ 🔍
ถ้าตั้งค่าครบแล้ว WebSocket จะนิ่งขึ้นมาก ทั้งเรื่อง connect, reconnect และการรับส่งข้อมูลแบบ real-time เหมาะกับระบบแชต, terminal บนเว็บ, trading panel, monitoring dashboard และ collaborative app 🚀📈💻
สรุปสั้นๆ Nginx ที่ใช้กับ WebSocket ควรเช็ก 5 จุด HTTP/1.1 Upgrade header Connection header Timeout เส้นทาง proxy ให้ตรงกับ backend ✅
ตั้งถูกไม่กี่บรรทัด แต่ช่วยลดบั๊กที่หายากในระบบ production ได้เยอะมาก 🔥
แนวทางนำไปใช้
- นำแนวคิดจากโพสต์นี้ไปทดลองกับงานจริงของคุณ
- แยกเป็นขั้นตอนเล็ก ๆ แล้วทำทีละส่วน
- บันทึกผลลัพธ์และสิ่งที่เรียนรู้เพื่อต่อยอด
สรุป
ทำความเข้าใจ Upgrade header, Connection header, timeout และ proxy configuration ที่จำเป็นเมื่อให้ Nginx ส่งต่อ WebSocket ไปยัง backend แบบ real-time