حل خطأ 502 Bad Gateway في Nginx وPHP-FPM
حل خطأ 502 بين Nginx وPHP-FPM بفحص السجلات والخدمة ومسار Socket والصلاحيات والذاكرة والطلبات البطيئة قبل تغيير المهلات.
خطأ 502 يعني أن Nginx لم يحصل على استجابة سليمة من الـupstream. ابدأ برسالة الخطأ الفعلية، ثم افحص PHP-FPM ومسار الاتصال والصلاحيات والموارد بهذا الترتيب.
لا يكشف 502 Bad Gateway السبب وحده. يعني الخطأ أن Nginx حاول الاتصال بالخدمة الخلفية ولم يحصل على استجابة صالحة. في تطبيقات PHP تكون الخدمة غالباً PHP-FPM، وقد يكون السبب مسار Socket خاطئاً أو خدمة متوقفة أو صلاحيات ناقصة أو عملية انهارت أو طلباً بطيئاً.
لا تبدأ برفع كل قيم الـTimeout. سجل وقت الطلب ومساره، ثم ابحث عن الرسالة المقابلة في السجلات.
ابدأ من السجلات لا من التخمين
أعد تنفيذ الطلب مرة واحدة ثم افحص:
sudo tail -n 100 /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm --since "10 minutes ago"
sudo systemctl status php8.3-fpm --no-pager
استبدل php8.3-fpm باسم الخدمة الموجودة على السيرفر. لمعرفة الخدمات المتاحة:
systemctl list-units --type=service | grep -E 'php.*fpm'
رسائل Nginx تعطيك اتجاه التحقيق:
No such file or directory: مسار الـSocket في Nginx لا يطابق PHP-FPM.Permission denied: مستخدم Nginx لا يستطيع الوصول إلى الـSocket أو أحد المجلدات الأب.Connection refused: لا توجد خدمة تستمع على العنوان أو المنفذ.upstream timed out: تم الاتصال، لكن PHP-FPM لم يرسل بيانات خلال المهلة.upstream prematurely closed FastCGI stdout: غالباً حدث Fatal Error أو انتهت العملية أو نفدت الموارد.
إن كان الموقع خلف CDN أو Proxy آخر، تأكد أولاً أن Nginx لديك هو مصدر الاستجابة 502.
افحص Nginx وPHP-FPM كلاً على حدة
تحقق من صحة إعداد Nginx:
sudo nginx -t
sudo systemctl status nginx --no-pager
ثم افحص PHP-FPM:
sudo systemctl is-active php8.3-fpm
sudo systemctl restart php8.3-fpm
sudo journalctl -u php8.3-fpm -n 100 --no-pager
قد يعيد الـRestart الموقع للعمل، لكنه لا يشرح سبب التوقف. اقرأ السجل بعده لتعرف إن كانت المشكلة ملف إعداد غير صالح، Extension مفقود، نقص ذاكرة، أو خطأ يتكرر.
يمكن التحقق من إعداد FPM عبر الـBinary المناسب للتوزيعة:
sudo php-fpm8.3 -tt
لا تفترض اسم الإصدار؛ استخدم command -v أو راجع ملف خدمة systemd.
طابق fastcgi_pass مع listen
إذا كان Nginx يستخدم Unix Socket:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
فيجب أن يطابق Pool الخاص بـPHP-FPM، وغالباً يوجد في ملف مثل:
; /etc/php/8.3/fpm/pool.d/www.conf
listen = /run/php/php8.3-fpm.sock
اعرض الـSockets والمنافذ الفعلية:
sudo find /run/php -maxdepth 1 -type s -ls
sudo ss -ltnp | grep php
عند استخدام TCP يجب أن يتطابق الطرفان، مثلاً 127.0.0.1:9000. لا تجعل PHP-FPM يستمع على واجهة عامة.
بعد التعديل:
sudo nginx -t && sudo systemctl reload nginx
sudo systemctl restart php8.3-fpm
أصلح الصلاحيات من المصدر
عند ظهور Permission denied اعرف مستخدم Nginx وملكية الـSocket:
ps -o user,group,cmd -C nginx
sudo stat /run/php/php8.3-fpm.sock
اضبط Pool بدلاً من تنفيذ chmod مؤقت يختفي مع إعادة التشغيل:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
قد يكون المستخدم nginx في بعض التوزيعات. راجع أيضاً صلاحية المرور داخل المجلدات الأب. استخدام 0777 ليس حلاً آمناً.
افحص الضغط والذاكرة والطلبات البطيئة
إذا ظهر 502 أثناء الضغط فقط:
free -h
df -h
sudo dmesg -T | grep -i -E 'out of memory|killed process'
sudo journalctl -u php8.3-fpm -p warning --since today
راجع pm.max_children بناءً على استهلاك العملية الحقيقي والذاكرة المتاحة. رفع العدد بلا حساب قد يجعل Kernel يقتل PHP Processes ويزيد المشكلة.
إن كان الطلب ينفذ تقريراً ثقيلاً أو ينتظر API خارجية، فعّل Slow Log مؤقتاً وافحص التطبيق وقاعدة البيانات. الأعمال الطويلة غالباً أنسب داخل Queue؛ راجع حل مشكلة Laravel Queue وإعداد Supervisor.
لا ترفع fastcgi_read_timeout إلا بعد إثبات أن Endpoint شرعي يحتاج زمناً أطول. وفق توثيق Nginx، القيمة تقيس الزمن بين عمليتي قراءة متتاليتين من FastCGI وليست مهلة كلية للطلب.
تأكد من نجاح الحل
اختبر Health Endpoint والمسار الذي كان يفشل:
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' \
https://example.com/health
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' \
https://example.com/original-path
تأكد من الآتي:
nginx -tينجح.- تبقى خدمتا Nginx وPHP-FPM في حالة Active.
- لا تظهر رسالة upstream جديدة في السجل.
- لا تعود المشكلة بعد Deploy أو Restart.
- المراقبة تفحص الموقع وحالة PHP-FPM والذاكرة.
أخطاء شائعة ومنع التكرار
أكثر الأخطاء شيوعاً: ربط Nginx بـSocket لإصدار PHP قديم، تعديل الصلاحيات يدوياً، رفع المهلات كلها، وتشغيل عدد Workers أكبر من قدرة الذاكرة.
ضع إعدادات Nginx وPHP-FPM في Version Control، واختبرها أثناء النشر، وراقب زمن upstream ومعدل 5xx. تكمل قائمة مراجعة Nginx Reverse Proxy الصورة التشغيلية.
أسئلة شائعة
هل انتهت المشكلة إذا اختفى 502 بعد Restart؟
عادت الخدمة، لكن السبب قد يتكرر. راجع السجل قبل Restart والذاكرة وPool Limits وأحداث النشر حتى تعرف لماذا توقفت PHP-FPM.
هل أستخدم Unix Socket أم TCP بين Nginx وPHP-FPM؟
كلاهما صالح. Socket شائعة داخل Host واحدة، وTCP أوضح بين Containers. الأهم Listener خاصة وإعداد متطابق وصلاحيات ومراقبة صحيحة.
مراجع رسمية
لديك سؤال عن هذا الدليل أو فكرة لتعاون تقني؟ تواصل مع بكري عبر المركز التقني.
نهاية الملاحظة.