Nginx เป็น Reverse Proxy สำหรับ Node.js/Python App บน VPS

บทนำ

Nginx Reverse Proxy เป็นเครื่องมือที่ช่วยให้คุณกระจาย Request ไปยัง Backend Applications เช่น Node.js, Python, Django หรือ Flask ที่ทำงานบน Cloud VPS บทความนี้จะอธิบายวิธีการตั้งค่า proxy_pass, Headers, WebSocket Support เพื่อให้แอปพลิเคชันของคุณทำงานได้อย่างมีประสิทธิภาพและปลอดภัย

Reverse Proxy คืออะไร

Reverse Proxy คือการตั้งค่าให้ Nginx ทำหน้าที่เป็นตัวกลางระหว่าง Client และ Backend Application Server ความดีของการใช้ Reverse Proxy คือ:

  • กระจาย (Distribute) Request ไปยังหลาย Backend Servers
  • ซ่อน Architecture ของ Application ของคุณ
  • ให้ SSL/TLS Termination ที่ Nginx หน้า Application
  • Cache Response เพื่อลดการใช้งาน Backend Server

ตั้งค่า proxy_pass สำหรับ Node.js

proxy_pass ใช้สำหรับบอก Nginx ว่าต้องส่ง Request ไปยัง Backend URL ใด ตัวอย่างการตั้งค่าสำหรับ Node.js Application ที่ทำงานบน Port 3000:

server {
    listen 80;
    server_name example.com;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

การตั้งค่านี้จะช่วยให้ WebSocket ทำงานได้อย่างถูกต้องสำหรับ Real-time Applications

ตั้งค่า proxy_pass สำหรับ Python/Django

สำหรับ Django Application ที่ทำงานบน Port 8000 ผ่าน Gunicorn:

location / {
    proxy_pass http://localhost:8000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;
}

ตั้งค่า HTTP Headers ที่สำคัญ

การส่ง Headers ที่ถูกต้องเป็นสิ่งสำคัญที่ Backend Application ต้องรู้ข้อมูล Client จริง:

location / {
    proxy_pass http://backend;
    
    # ส่ง Host Header ต้นฉบับ
    proxy_set_header Host $host;
    
    # ส่ง IP Address ของ Client จริง
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
    # ส่ง Protocol ที่ Client ใช้ (HTTP หรือ HTTPS)
    proxy_set_header X-Forwarded-Proto $scheme;
    
    # ส่ง Host ต้นฉบับ
    proxy_set_header X-Forwarded-Host $server_name;
}

WebSocket Support

สำหรับ Real-time Applications ที่ใช้ WebSocket (เช่น Socket.io, SignalR) ต้องตั้งค่า Headers พิเศษ:

location /socket.io {
    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_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

ส่วน Upgrade Header ช่วยให้ Nginx รู้ว่า Connection นี้ต้องอัพเกรดเป็น WebSocket

ตั้งค่า Timeouts

สำหรับ Request ที่ใช้เวลานาน ต้องตั้งค่า Timeout ให้เหมาะสม:

location / {
    proxy_pass http://backend;
    
    # Timeout สามค่าสำคัญ
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    
    # เปิด Buffering
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
    proxy_busy_buffers_size 8k;
}

Load Balancing กับ Upstream

หากมีหลาย Backend Servers ให้ใช้ upstream สำหรับ Load Balancing:

upstream backend {
    server localhost:3000;
    server localhost:3001;
    server localhost:3002;
}

server {
    listen 80;
    server_name example.com;
    
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Nginx จะกระจาย Request แบบ Round-robin ไปยังแต่ละ Backend Server โดยอัตโนมัติ

ตัวอย่าง Flask Application

สำหรับ Flask Application ที่ทำงานบน Port 5000:

location / {
    proxy_pass http://127.0.0.1:5000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;
}

ตัวอย่าง ASP.NET Core Application

สำหรับ ASP.NET Core ที่ทำงานบน Port 5000:

location / {
    proxy_pass http://localhost:5000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection keep-alive;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}