กลับไปหน้าบทความ
#Nginx#Routing#Configuration#DevOps

เข้าใจลำดับการจับคู่ Nginx Location ไม่ให้ Request วิ่งผิด Block

อธิบายความสำคัญของ exact match, prefix และ regular expression location พร้อมวิธีตรวจ config เมื่อหลาย block ซ้อนกันและ routing ไม่ทำงานตามที่คาด

9 กรกฎาคม 2569อ่านประมาณ 2 นาที

แชร์บทความ

เข้าใจลำดับการจับคู่ Nginx Location ไม่ให้ Request วิ่งผิด Block

ภาพรวม

หลายคนใช้ Nginx มานาน แต่ยังเคยงงว่าเขียน location หลายอันแล้วทำไมมันไม่วิ่งเข้า block ที่คิดไว้ 🤯

เบื้องหลังของ Nginx Location Matching มีลำดับการเลือกที่ค่อนข้างเป๊ะ และถ้าเข้าใจตรงนี้จะ debug config ได้ไวขึ้นมาก ⚙️

สิ่งที่น่าสนใจคือ Nginx ไม่ได้เลือก location ตามลำดับที่เขียนในไฟล์เสมอไป

มันมี “กติกาการจับคู่” ของตัวเอง และบางครั้ง regex ที่คิดว่าจะชนะ กลับแพ้ prefix ที่ใส่เครื่องหมายพิเศษไว้ 😵‍💫

หลักที่ควรรู้มีอยู่ 4 แบบ 🧩

location = /path ใช้จับคู่แบบเป๊ะทั้งเส้นทาง

location /path ใช้จับคู่แบบ prefix หรือขึ้นต้นด้วย path นี้

location ^~ /path ใช้จับคู่แบบ prefix เหมือนกัน แต่ถ้าแมตช์แล้ว Nginx จะไม่ไปเช็ก regex ต่อ 🚀

location ~ regex จับคู่ด้วย regex แบบแยกตัวพิมพ์เล็กใหญ่

location ~* regex จับคู่ด้วย regex แบบไม่แยกตัวพิมพ์เล็กใหญ่ 🔍

ลำดับการตัดสินใจโดยย่อมีแบบนี้

  1. เช็ก exact match ก่อน ถ้าเจอ location = /something จะเลือกอันทันที ✅

  2. เช็ก prefix match ที่ยาวที่สุด Nginx จะมองหา prefix ที่ตรงที่สุด ไม่ใช่อันที่เขียนก่อน

  3. ถ้า prefix ที่ชนะมี ^~ เกมจบทันที ใช้อันนั้นเลย ไม่ไปดู regex 🔒

  4. ถ้าไม่มี ^~ Nginx จะไล่เช็ก regex ตามลำดับที่เขียนจากบนลงล่าง อันแรกที่แมตช์จะชนะ 🎯

  5. ถ้า regex ไม่แมตช์เลย กลับไปใช้ prefix ที่ยาวที่สุดที่หาไว้ก่อนหน้า

ตัวอย่างที่ทำให้หลายคนพลาดบ่อย 👇

location /images/ location ~* .(jpg|png|gif)$

ถ้า request เป็น /images/logo.png หลายคนคิดว่าจะเข้า /images/ แต่จริงๆ regex มีสิทธิ์ชนะ ถ้าไม่มี ^~ อยู่ที่ prefix 🧠

ถ้าเปลี่ยนเป็น location ^~ /images/ location ~* .(jpg|png|gif)$

แบบนี้ /images/logo.png จะเข้า block /images/ ทันที regex หมดสิทธิ์แทรก 🛑

อีกเคสที่เจอบ่อยในงาน API

location /api/ location /api/v1/ location ~ ^/api/.*/admin

ถ้าเรียก /api/v1/user/admin Nginx จะหา prefix ที่ยาวที่สุดก่อน ซึ่งก็คือ /api/v1/ แต่ถ้าไม่มี ^~ มันยังไปเช็ก regex ต่อ และ regex อาจชนะได้ ⚠️

แปลว่า prefix ที่ยาวที่สุด ไม่ได้แปลว่าจะถูกใช้เสมอ ถ้ายังเปิดทางให้ regex เข้ามาแข่ง

ทริคที่ช่วยลดบั๊กใน production 🧰

ใช้ = กับ path สำคัญ เช่น / หรือ /health ถ้าต้องการความชัดเจนสูง

ใช้ ^~ กับ static files หรือ path ที่ไม่อยากให้ regex มายุ่ง เช่น /assets/ /images/ /static/ 📦

ระวัง regex ที่กว้างเกินไป เพราะอาจแย่ง request จาก location ที่ตั้งใจไว้

ถ้ามีหลาย regex จำไว้ว่า Nginx ใช้อันแรกที่แมตช์ ไม่ได้เลือกอันที่ดูเฉพาะเจาะจงที่สุด ✍️

เวลางงว่า request เข้าบล็อกไหน ให้เปิด debug log หรือแยกทดสอบทีละ location จะเห็นพฤติกรรมชัดขึ้น 🔬

อีกจุดที่คนมักไม่รู้ การทำงานของ location เป็นเรื่องของ URI matching ไม่ใช่ filesystem matching โดยตรง

แปลว่า path ที่เห็นใน URL กับ path จริงบนดิสก์เป็นคนละขั้นตอนกัน 🗂️ หลังจากเลือก location ได้แล้ว ค่อยไปดูต่อว่าจะใช้ root, alias, rewrite หรือ proxy_pass ยังไง

ตัวอย่าง mental model สั้นๆ 🧠

เป๊ะมาก่อน ยาวสุดมาก่อน ถ้าใส่ ^~ ให้หยุดเลย ถ้าไม่หยุด ค่อยเปิดศึก regex

จำ 4 บรรทัดนี้ได้ เวลาอ่าน config คนอื่นจะไวขึ้นมาก ⏱️

เรื่องนี้เล็กมากในสายตาหลายคน แต่ในระบบจริงมันทำให้เกิดทั้ง 404 แปลกๆ, static file หลุดไปเข้า app server, หรือ cache ไม่ทำงานได้เลย 💥

เข้าใจ Location Matching ดีครั้งเดียว จะช่วยให้ config Nginx อ่านง่ายขึ้น ดูแลง่ายขึ้น และมั่นใจเวลาปรับ route หน้าเว็บหรือ API มากขึ้น 🌐

แนวทางนำไปใช้

  • นำแนวคิดจากโพสต์นี้ไปทดลองกับงานจริงของคุณ
  • แยกเป็นขั้นตอนเล็ก ๆ แล้วทำทีละส่วน
  • บันทึกผลลัพธ์และสิ่งที่เรียนรู้เพื่อต่อยอด

สรุป

อธิบายความสำคัญของ exact match, prefix และ regular expression location พร้อมวิธีตรวจ config เมื่อหลาย block ซ้อนกันและ routing ไม่ทำงานตามที่คาด