خطای 502 یعنی Nginx درخواست را به برنامهٔ پشتی (PHP-FPM، Node.js، پایتون یا کانتینر) فرستاده اما پاسخ معتبری نگرفته است. اولین قدم خواندن /var/log/nginx/error.log است؛ پیامهایی مثل connect() failed، Connection refused یا upstream prematurely closed مستقیم علت را نشان میدهند. بیشتر وقتها برنامهٔ پشتی متوقف شده، آدرس یا سوکت در proxy_pass اشتباه است، مجوز سوکت درست نیست یا برنامه بهدلیل کمبود رم kill شده است.
خطای 502 دقیقاً یعنی چه؟
Nginx در بیشتر سرورها نقش «دروازه» یا Reverse Proxy را دارد: درخواست کاربر را میگیرد و آن را به برنامهای که پشتش است میفرستد. این برنامه ممکن است PHP-FPM برای وردپرس و لاراول، Gunicorn برای جنگو، یک برنامهٔ Node.js یا یک کانتینر داکر باشد. وقتی Nginx نتواند به این برنامه وصل شود یا پاسخ نامعتبر و ناقص بگیرد، به کاربر خطای 502 Bad Gateway نشان میدهد.
پس نکتهٔ کلیدی این است: خطای 502 تقریباً هیچوقت مشکل خود Nginx نیست؛ Nginx فقط پیامرسان است و میگوید «پشت من کسی جواب نمیدهد». عیبیابی باید روی ارتباط Nginx با برنامهٔ پشتی (Upstream) متمرکز شود.
اگر سایت شما پشت CDN است، ممکن است خطای 502 را خود CDN نشان دهد، نه Nginx سرور شما. در این حالت ابتدا مطمئن شوید سرور اصلی مستقیم پاسخ میدهد؛ راهنمای خطاهای 5xx در CDN تفاوت این دو حالت را توضیح میدهد.
گام اول: لاگ خطای Nginx را بخوانید
هر عیبیابی 502 باید با لاگ شروع شود. پیام لاگ معمولاً علت را دقیقاً نام میبرد:
sudo tail -n 50 /var/log/nginx/error.log
# یا دنبال کردن زنده هنگام باز کردن صفحه
sudo tail -f /var/log/nginx/error.log
پیامهای رایج و معنایشان:
| پیام در لاگ | معنی |
|---|---|
connect() failed (111: Connection refused) |
برنامهٔ پشتی روی آن پورت در حال اجرا نیست |
connect() to unix:/run/php/... failed (2: No such file or directory) |
مسیر سوکت PHP-FPM اشتباه است یا سرویس متوقف شده |
connect() to unix:... failed (13: Permission denied) |
کاربر Nginx اجازهٔ دسترسی به سوکت را ندارد |
upstream prematurely closed connection |
برنامه وسط پاسخ از کار افتاد یا اتصال را بست |
upstream sent too big header |
هدر پاسخ از بافر Nginx بزرگتر است |
no live upstreams |
همهٔ سرورهای پشتی تعریفشده از دسترس خارجاند |
علت ۱: برنامهٔ پشتی اجرا نمیشود
رایجترین علت این است که برنامه متوقف شده یا هنگام اجرا خطا داده است. وضعیت سرویس را بررسی کنید:
sudo systemctl status php8.3-fpm # نسخهٔ PHP خود را بنویسید
sudo systemctl status myapp # سرویس برنامهٔ خودتان
docker ps -a # اگر برنامه در کانتینر است
اگر سرویس متوقف است، لاگش را ببینید تا بفهمید چرا از کار افتاده و بعد اجرایش کنید:
sudo journalctl -u myapp -n 100 --no-pager
sudo systemctl restart myapp
برای اینکه برنامه پس از خطا یا ریاستارت سرور خودکار بالا بیاید، باید آن را بهصورت سرویس systemd با Restart=always تعریف کنید؛ نمونهٔ کامل را در اجرای دائمی برنامه با systemd ببینید.
علت ۲: آدرس، پورت یا سوکت اشتباه
مقداری که در proxy_pass یا fastcgi_pass نوشتهاید باید دقیقاً با جایی که برنامه گوش میدهد یکی باشد. ابتدا ببینید برنامه واقعاً روی کجا گوش میدهد:
sudo ss -tlnp | grep -E "8000|3000|9000"
ls -l /run/php/
سپس با پیکربندی Nginx مقایسه کنید. چند اشتباه رایج:
- برنامه روی
127.0.0.1:3000است اما در Nginx پورت8000نوشته شده. - PHP به نسخهٔ جدید ارتقا یافته و نام سوکت از
php8.1-fpm.sockبهphp8.3-fpm.sockتغییر کرده، ولی Nginx هنوز آدرس قدیمی را دارد. - برنامه داخل کانتینر روی
127.0.0.1گوش میدهد و از بیرون کانتینر در دسترس نیست؛ داخل کانتینر باید روی0.0.0.0گوش دهد و پورت منتشر شود.
پس از اصلاح پیکربندی، همیشه پیش از بارگذاری دوباره آن را تست کنید:
sudo nginx -t && sudo systemctl reload nginx
درستی ارتباط را میتوانید بدون Nginx هم تست کنید: curl -I http://127.0.0.1:8000. اگر این دستور جواب ندهد، مشکل در برنامه است نه Nginx.
$ tail -n 2 /var/log/nginx/error.log... connect() failed (111: Connection refused) while connecting to upstream, upstream: "http://127.0.0.1:8000/"$ ss -tlnp | grep 8000$ systemctl status myapp --no-pager | head -n 3 Active: failed (Result: exit-code)$
علت ۳: مجوز دسترسی به سوکت
وقتی Nginx و برنامه از طریق سوکت یونیکس (فایل .sock) با هم صحبت میکنند، کاربر Nginx (معمولاً www-data) باید اجازهٔ خواندن و نوشتن روی آن فایل را داشته باشد. در PHP-FPM این تنظیم در فایل pool است:
; /etc/php/8.3/fpm/pool.d/www.conf
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
برای Gunicorn یا برنامههای دیگر هم کاربری که برنامه را اجرا میکند و گروه سوکت را بررسی کنید. اگر SELinux فعال است (در AlmaLinux و Rocky)، ممکن است اتصال Nginx به شبکه را مسدود کند؛ با setsebool -P httpd_can_network_connect 1 این اجازه داده میشود.
علت ۴: کمبود رم و kill شدن برنامه
اگر خطای 502 بهصورت گاهبهگاه و در ساعتهای شلوغ رخ میدهد و پیام upstream prematurely closed در لاگ است، احتمال زیادی دارد که برنامه بهدلیل کمبود رم توسط هسته kill شده باشد:
sudo dmesg -T | grep -i -E "killed process|out of memory"
free -h
راهحلها: کاهش تعداد پردازشهای همزمان (مثلاً pm.max_children در PHP-FPM یا تعداد workerهای Gunicorn) متناسب با رم، افزودن Swap بهعنوان حاشیهٔ امن و در نهایت ارتقای رم. توضیح کامل در کمبود رم سرور و خطای Out of Memory آمده است.
علت ۵: هدر بزرگ و تنظیمات بافر
برخی برنامهها، بهخصوص وقتی کوکیهای زیاد یا هدرهای بزرگ میفرستند، باعث پیام upstream sent too big header میشوند. افزایش بافر در بلوک مربوط مشکل را حل میکند:
proxy_buffer_size 16k;
proxy_buffers 8 16k;
# برای PHP-FPM:
fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;
حالتهای خاص: داکر و CDN
برنامه در کانتینر داکر: وقتی Nginx روی خود سرور نصب است و برنامه در کانتینر، بررسی کنید پورت کانتینر واقعاً منتشر شده باشد (docker ps ستون PORTS را نشان میدهد). اگر Nginx هم در کانتینر است، آدرس 127.0.0.1 به خود کانتینر Nginx اشاره میکند، نه برنامه؛ هر دو را در یک شبکهٔ داکر قرار دهید و در proxy_pass از نام سرویس استفاده کنید. همچنین پس از هر بار ساخت دوباره، کانتینر ممکن است آیپی داخلی جدیدی بگیرد؛ استفاده از نام سرویس بهجای آیپی این مشکل را از بین میبرد.
سایت پشت CDN: اگر بازدیدکننده صفحهٔ خطای 502 با طراحی CDN میبیند، ابتدا از روی خود سرور با curl -I http://127.0.0.1 و سپس از بیرون با آیپی مستقیم سرور تست کنید. اگر سرور مستقیم پاسخ درست میدهد، مشکل در اتصال CDN به سرور است؛ مثلاً فایروال آیپیهای CDN را بسته، پورت یا حالت SSL در تنظیمات CDN اشتباه است یا گواهی سرور منقضی شده است.
تفاوت 502 با 504
خطای 504 (Gateway Timeout) یعنی Nginx به برنامه وصل شده اما برنامه در زمان مقرر پاسخ نداده است؛ معمولاً بهخاطر کوئری کند دیتابیس یا پردازش طولانی. در حالی که 502 یعنی اتصال اصلاً برقرار نشده یا پاسخ نامعتبر بوده است. این تمایز مهم است، چون راهحل 504 معمولاً بهینهسازی برنامه یا افزایش timeout است، نه بررسی پورت و سوکت.
- اتصال به بکاند برقرار نشد
- یا پاسخ نامعتبر و ناقص بود
- علت: سرویس متوقف، پورت یا سوکت اشتباه، مجوز
- راهحل: اجرای سرویس و اصلاح آدرس
- اتصال برقرار شد
- اما پاسخ در زمان مقرر نرسید
- علت: کوئری یا پردازش کند
- راهحل: بهینهسازی یا افزایش timeout
چکلیست سریع رفع 502
error.logرا بخوانید و پیام دقیق را پیدا کنید.- وضعیت سرویس برنامه را با systemctl یا docker ps بررسی کنید.
- با
ss -tlnpوcurlمطمئن شوید برنامه روی آدرس درست پاسخ میدهد. proxy_passیاfastcgi_passرا با آدرس واقعی مقایسه کنید وnginx -tبگیرید.- مجوز سوکت و SELinux را بررسی کنید.
- لاگ هسته را برای kill شدن بهدلیل کمبود رم ببینید.
اگر پیکربندی Nginx را تازه انجام دادهاید، آموزش Nginx و گواهی Let's Encrypt نمونهٔ پیکربندی درست را نشان میدهد. و اگر سرور شما مدام زیر بار کم میآورد، شاید وقت ارتقای منابع رسیده باشد؛ پلنهای سرور مجازی ایران کلودیفای ساعتی هستند و میتوانید پلن بزرگتر را بدون تعهد ماهانه امتحان کنید.
سؤالات متداول
خطای 502 از سمت سرور است یا کاربر؟
تقریباً همیشه از سمت سرور است. پاک کردن کش مرورگر یا عوض کردن اینترنت کاربر معمولاً اثری ندارد، چون Nginx نتوانسته پاسخی از برنامهٔ پشتی بگیرد. علت را باید در لاگ سرور جستوجو کرد.
چرا بعد از ارتقای PHP خطای 502 گرفتم؟
با ارتقای PHP نام سرویس و مسیر سوکت عوض میشود. اگر fastcgi_pass در پیکربندی Nginx هنوز به سوکت نسخهٔ قبلی اشاره کند، اتصال برقرار نمیشود. مسیر را با ls /run/php پیدا و در Nginx اصلاح کنید.
خطای 502 فقط گاهی رخ میدهد؛ علتش چیست؟
خطای متناوب معمولاً به کمبود منابع مربوط است: برنامه در اوج بار بهدلیل کمبود رم kill میشود یا تعداد workerها کافی نیست. لاگ هسته و مصرف رم را در همان ساعتها بررسی کنید.
ریاستارت Nginx خطای 502 را رفع میکند؟
معمولاً نه، چون مشکل در برنامهٔ پشتی است. ریاستارت برنامه مثل PHP-FPM یا سرویس Node.js ممکن است موقتاً مشکل را حل کند، اما باید علت توقف آن را از لاگ پیدا کنید تا تکرار نشود.
از ۱٬۲۰۰ تومان در ساعت · پرداخت ریالی



