کانفیگ nginx reverse proxy برای Node.js و Next.js
برنامههایی مثل Node.js، Next.js، Django یا Go معمولاً روی یک پورت محلی (مثلاً ۳۰۰۰) اجرا میشوند. nginx جلوی آنها قرار میگیرد، SSL را مدیریت میکند، فایلهای استاتیک را سریعتر سرو میکند و درخواستها را به برنامه میرساند.
۱اجرای برنامه فقط روی localhost
برنامه را روی 127.0.0.1 گوش بدهید تا مستقیماً از اینترنت در دسترس نباشد و همهٔ ترافیک از nginx بگذرد. نمونه با Docker:
docker run -d --name app --restart unless-stopped -p 127.0.0.1:3000:3000 myapp:latest
curl -I http://127.0.0.1:3000۲تعریف WebSocket در بخش http (یک بار)
این map را یک بار در فایل جداگانهای داخل conf.d بگذارید تا همهٔ سایتها از آن استفاده کنند.
sudo nano /etc/nginx/conf.d/websocket-map.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}۳server block با reverse proxy
بلوک upstream چند ویژگی مفید دارد: نامگذاری برنامه، keepalive برای کاهش تعداد اتصالها و امکان افزودن سرور دیگر در آینده. هدرهای X-Forwarded-* به برنامه میگویند کاربر واقعی کیست.
sudo nano /etc/nginx/sites-available/app.example.com
upstream app_backend {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 80;
listen [::]:80;
server_name app.example.com;
client_max_body_size 20m;
location / {
proxy_pass http://app_backend;
proxy_http_version 1.1;
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;
# WebSocket و HTTP/1.1 keepalive
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}برای WebSocket طولانیمدت (مثل چت) proxy_read_timeout را بیشتر کنید، مثلاً 3600s.
۴فعالسازی و تست
لینک را بسازید، کانفیگ را تست و reload کنید.
sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
curl -I -H "Host: app.example.com" http://127.0.0.1۵سرو مستقیم فایلهای استاتیک با nginx (اختیاری، سریعتر)
برای Next.js و SPA ها میتوانید فایلهای ثابت را بدون رسیدن به برنامه از دیسک سرو کنید. مسیر alias را با مسیر واقعی پروژه عوض کنید.
location /_next/static/ {
alias /opt/myapp/.next/static/;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}۶برنامهای که زیر یک مسیر (subpath) قرار دارد
اگر میخواهید برنامه روی /dashboard/ باشد، به انتهای proxy_pass یک اسلش بدهید تا آن پیشوند حذف شود.
location /dashboard/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
}وجود یا نبود اسلش انتهای proxy_pass معنی متفاوتی دارد: با اسلش مسیر location جایگزین میشود و بدون آن مسیر کامل ارسال میشود.
۷عیبیابی خطای 502 Bad Gateway
یعنی nginx به برنامه وصل نشده. بررسی کنید برنامه اجرا و روی همان پورت است و لاگ خطا را ببینید.
ss -tlnp | grep 3000
docker ps
sudo tail -n 30 /var/log/nginx/error.logپرسشهای پرتکرار دربارهٔ کانفیگ nginx reverse proxy برای Node.js و Next.js
چرا برنامه IP کاربر را نمیبیند و همهجا 127.0.0.1 است؟
چون درخواست از nginx میآید. باید هدر X-Forwarded-For را در برنامه (مثلاً trust proxy در Express) بخوانید یا در nginx ماژول real_ip را تنظیم کنید.
چرا WebSocket قطع میشود؟
احتمالاً هدرهای Upgrade و Connection ارسال نمیشوند یا proxy_read_timeout کوتاه است. تنظیمات map و هدرهای این راهنما را بررسی کنید.