المستوى: مبتدئ
لو تطبيق Node.js أو Django عندك شغّال على بورت 3000 وفتحت الـ firewall ليه مباشرة، انت غالبًا بتدفع ضريبة 3 مشاكل في وقت واحد: HTTPS متعب، أي DDoS صغير بيقع السيرفر، ومش قادر تحط أكتر من تطبيق على نفس الجهاز. Reverse Proxy بـ NGINX بيحلّ التلاتة بـ 15 سطر إعداد فقط.
Reverse Proxy: ليه محتاجه أصلًا
تخيّل إنك بتدير عيادة فيها 4 أطباء. لو كل مريض دخل العيادة بيدوّر بنفسه على الدكتور الصح، هتحصل فوضى: مرضى تايهين في الطرقات، أطباء بيتقاطعوا، وحد بدون موعد ممكن يدخل عند أي حد. سكرتيرة الاستقبال بتاخد المريض، تشوف هو محتاج إيه، وتوجّهه للدكتور المناسب. كمان لو في زبون مزعج بيحاول يدخل بدون موعد، السكرتيرة بترفض من قبل ما يتعب الأطباء.
NGINX قدّام تطبيقك بيلعب دور سكرتيرة الاستقبال دي بالظبط. هو بيستقبل كل طلبات الإنترنت على بورت 80 و 443، يشوف الطلب رايح فين، ويوجّهه لتطبيقك الداخلي على البورت بتاعه. تطبيقك يفضل مخفي ومش متعرّض للإنترنت مباشرة، وأي طلب ضارّ بيتفلتر قبل ما يوصلّه.
المشكلة باختصار
تطبيق Express أو Django أو Flask بشكل افتراضي بيستمع على بورت زي 3000 أو 8000. ده بورت غير قياسي، ومحدش بيكتب http://example.com:3000 في المتصفح. عشان كده انت محتاج حاجة تشتغل على بورت 80 (HTTP القياسي) و 443 (HTTPS) وتحوّل الطلبات لتطبيقك.
الحل اللي بيتقال أحيانًا للمبتدئ هو إنك تشغّل تطبيقك مباشرة على بورت 80. الطريقة دي بتفشل في 3 حالات: محتاجة صلاحيات root خطيرة (لأن أي بورت أقل من 1024 محجوز للنظام)، مش بتدعم HTTPS بسهولة، وميقدرش يكون عندك تطبيق تاني على نفس السيرفر.
المفهوم بشكل علمي ودقيق
الـ Reverse Proxy هو سيرفر وسيط بيستقبل الطلبات من العميل (المتصفح)، ويوجّهها لسيرفر داخلي مناسب (تطبيقك)، ثم يرجّع الرد للعميل. الكلمة "Reverse" بتفرّقه عن Forward Proxy العادي اللي بيكون بين العميل والإنترنت لإخفاء هوية العميل. الـ Reverse Proxy بيكون بين الإنترنت والسيرفرات لإخفاء بنية السيرفرات الداخلية.
الافتراض إن عندك سيرفر Linux واحد على الأقل بـ NGINX أو Caddy أو Traefik مثبّت، وتطبيق واحد أو أكثر بتشتغل على بورتات داخلية (3000، 4000، 5000…) ومش بتسمع على الـ public IP مباشرة.
إعداد NGINX كـ Reverse Proxy في 15 سطر
بعد ما تثبّت NGINX على Ubuntu بأمر sudo apt install nginx، افتح ملف /etc/nginx/sites-available/myapp وحط فيه الإعداد ده:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}