دليل تشغيل Nginx Proxy Manager لربط الدومينات ببرامج Docker بسهولة
شرح عملي لتركيب Nginx Proxy Manager وربط Domains وSubdomains بتطبيقات Docker، مع SSL وDocker Networks وحل مشاكل 502 وWebSockets.
إذا كنت تشغّل أكثر من برنامج داخل Docker، ستصل بسرعة إلى مشكلة مزعجة: كل تطبيق يعمل على Port مختلفة.
مثلًا:
http://SERVER-IP:3000
http://SERVER-IP:8080
http://SERVER-IP:5678
http://SERVER-IP:2283
هذا مناسب أثناء التجربة، لكنه ليس الشكل الذي تريد تقديمه للمستخدمين.
الأفضل أن تصل إلى التطبيقات بهذه الصورة:
app.example.com
automation.example.com
photos.example.com
وهنا يأتي دور Nginx Proxy Manager.
هو Reverse Proxy بواجهة Web تساعدك على ربط Domains وSubdomains بالتطبيقات التي تعمل خلفه، مع إمكانية إصدار SSL وإدارة التحويلات دون كتابة إعداد Nginx كامل لكل برنامج.
قبل أن نبدأ: كيف ستتحرك الزيارة؟
لنفرض أن لديك تطبيقًا داخل Docker يعمل على Port 3000.
عندما يفتح المستخدم:
https://app.example.com
يحدث المسار التالي:
المستخدم
↓
DNS
↓
عنوان الـ Server
↓
Nginx Proxy Manager :443
↓
Docker Container :3000
↓
التطبيق
المستخدم لا يحتاج أن يعرف Port التطبيق الداخلية.
Nginx Proxy Manager هي التي تستقبل الطلب على Domain ثم ترسله إلى التطبيق الصحيح.
ما الذي تحتاجه قبل التركيب؟
قبل البدء تأكد من وجود:
- Server تعمل بنظام Linux.
- Docker مثبتة.
- Docker Compose متاحة.
- Domain تملك التحكم في DNS الخاصة بها.
- Ports 80 و443 قابلة للوصول من الإنترنت.
سنستخدم Port 81 للوصول إلى لوحة إدارة Nginx Proxy Manager، لكن لا نحتاج أن نجعلها متاحة للعالم إذا كان بالإمكان تقييد الوصول إليها.
1. أنشئ Network مشتركة للـ Reverse Proxy
هذه الخطوة مهمة جدًا إذا كنت تريد أن تتحدث Nginx Proxy Manager مباشرة مع Docker Containers بأسمائها.
أنشئ Network باسم:
docker network create proxy
تحتاج تنفيذ الأمر مرة واحدة فقط.
يمكن التأكد من وجودها بواسطة:
docker network ls
ميزة الـ Network المشتركة أننا نستطيع لاحقًا جعل Nginx Proxy Manager تتصل مثلًا بخدمة اسمها:
myapp:3000
بدل الاعتماد على IP متغيرة لكل Container.
2. أنشئ مجلد Nginx Proxy Manager
mkdir -p ~/nginx-proxy-manager
cd ~/nginx-proxy-manager
ثم أنشئ ملف:
compose.yml
واكتب فيه:
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "81:81"
- "443:443"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy
networks:
proxy:
external: true
ماذا يفعل هذا Compose؟
لدينا ثلاثة Ports مهمة:
- 80 لاستقبال HTTP.
- 443 لاستقبال HTTPS.
- 81 للوحة إدارة Nginx Proxy Manager.
أما:
./data:/data
فتحفظ بيانات وإعدادات Nginx Proxy Manager.
و:
./letsencrypt:/etc/letsencrypt
تحتفظ ببيانات Certificates.
ملفات الإعداد والشهادات موجودة في Volumes خارج الطبقة المؤقتة للـ Container، لذلك يمكن إعادة إنشاء Container دون فقد الإعدادات المخزنة في هذه المسارات. ومع ذلك، وجود Volumes لا يغني عن Backup منفصلة.
3. شغّل Nginx Proxy Manager
من داخل المجلد نفذ:
docker compose up -d
ثم تحقق:
docker compose ps
ولمشاهدة Logs:
docker compose logs -f
عندما تعمل الخدمة بصورة طبيعية، افتح:
http://SERVER-IP:81
وأكمل إعداد حساب الإدارة الذي تعرضه لك النسخة المستخدمة.
بعد الدخول، استخدم Password قوية، ولا تترك وصول لوحة الإدارة مفتوحًا أكثر مما تحتاج.
4. جهّز DNS قبل إنشاء Proxy Host
لنفرض أن الـ Server عنوانها:
203.0.113.10
وتريد استخدام:
app.example.com
داخل DNS أضف عادة سجل:
Type: A
Name: app
Value: 203.0.113.10
بهذا يصبح Subdomain يشير إلى الـ Server التي تشغل Nginx Proxy Manager.
انتظر حتى يبدأ DNS بالظهور من الإنترنت قبل تشخيص SSL على أنها مشكلة في Nginx Proxy Manager.
5. الآن نحتاج تطبيق Docker لربطه
لنفترض أن لديك تطبيقًا باسم:
myapp
ويستمع داخل Container على:
3000
نريد أن يكون التطبيق وNginx Proxy Manager داخل Network نفسها.
في Compose الخاصة بالتطبيق يمكن أن يكون لديك:
services:
myapp:
image: example/myapp:latest
restart: unless-stopped
networks:
- proxy
networks:
proxy:
external: true
لاحظ أننا لم نحتج إلى كتابة:
ports:
- "3000:3000"
إذا كان الوصول إلى التطبيق مطلوبًا فقط من Nginx Proxy Manager عبر Network الداخلية.
بهذا نقلل الخدمات التي نكشفها مباشرة على Host.
6. أضف Proxy Host
من لوحة Nginx Proxy Manager افتح:
Hosts
→ Proxy Hosts
→ Add Proxy Host
في Domain Names اكتب:
app.example.com
في Scheme اختر عادة:
http
إذا كان التطبيق الداخلي يعمل HTTP.
وفي Forward Hostname / IP اكتب:
myapp
وفي Forward Port:
3000
ثم احفظ.
أصبحت Nginx Proxy Manager تعرف أن كل طلب يصل إلى:
app.example.com
يجب أن يذهب إلى:
myapp:3000
لماذا نستطيع كتابة myapp بدل IP؟
لأن Container الخاصة بـNginx Proxy Manager وContainer الخاصة بالتطبيق موجودتان على Docker Network مشتركة.
Docker توفر Name Resolution داخل الشبكة، لذلك يمكن استخدام اسم Service أو Container المناسب بدل مطاردة IP قد تتغير بعد إعادة الإنشاء.
7. جرّب HTTP أولًا
قبل الانتقال إلى SSL، افتح:
http://app.example.com
إذا ظهر التطبيق فلدينا ثلاثة أجزاء تعمل:
- DNS تشير إلى الـ Server الصحيحة.
- Nginx Proxy Manager تستقبل الطلب.
- Nginx Proxy Manager تستطيع الوصول إلى Container الهدف.
إذا لم يعمل، لا تبدأ بتغيير عشرة إعدادات في الوقت نفسه.
اختبر كل طبقة على حدة.
8. فعّل SSL
افتح Proxy Host التي أنشأتها ثم انتقل إلى قسم:
SSL
اختر طلب SSL Certificate جديدة عندما يناسب إعداد Domain، ثم فعّل الخيارات المطلوبة مثل:
Force SSL
بعد نجاح إصدار الشهادة يصبح الوصول:
https://app.example.com
ويستقبل المستخدم HTTPS، بينما يمكن أن يبقى الاتصال الداخلي بين Nginx Proxy Manager والتطبيق HTTP داخل Docker Network.
لماذا قد يفشل إصدار SSL؟
قبل افتراض أن المشكلة في Let's Encrypt، تحقق من الأساسيات:
- Domain تشير إلى Public IP الصحيحة.
- Port 80 تصل إلى Nginx Proxy Manager.
- Port 443 غير محجوزة بواسطة برنامج آخر.
- Firewall لا تمنع الوصول المطلوب.
- DNS انتهت من الانتشار بالقدر اللازم للوصول إلى الوجهة الصحيحة.
إذا كان هناك Web Server آخر يحتل Port 80 أو 443 على Host نفسها، فلن تستطيع Nginx Proxy Manager استخدام Port نفسها في الوقت نفسه.
9. ماذا لو كان التطبيق على Server أخرى؟
ليس شرطًا أن تكون كل البرامج داخل Docker Network نفسها.
يمكن أن يكون التطبيق على جهاز آخر داخل الشبكة.
مثلًا:
Forward Hostname / IP:
192.168.1.50
Forward Port:
8080
المهم أن Nginx Proxy Manager تستطيع الوصول إلى ذلك العنوان والـPort من مكان تشغيلها.
في هذه الحالة لا نستفيد من Docker DNS Name، لذلك نستخدم IP أو Hostname يمكن الوصول إليها.
10. ماذا لو كان التطبيق على Host نفسها لكنه خارج Network؟
هنا تحتاج إلى عنوان يستطيع Nginx Proxy Manager الوصول من خلاله إلى الخدمة.
لا تستخدم:
127.0.0.1
وتفترض دائمًا أنها Host، لأن localhost داخل Container تشير إلى Container نفسها.
استخدم Network مناسبة أو عنوان Host يمكن الوصول إليه من Container بحسب بنية Server.
عندما تكتب 127.0.0.1 داخل Container، فأنت تشير إلى Container نفسها، وليس تلقائيًا إلى نظام Linux الذي يشغل Docker.
11. WebSockets
بعض التطبيقات تستخدم WebSockets لاتصالات مستمرة أو تحديثات فورية.
إذا كان التطبيق يحتاجها، فعّل خيار:
Websockets Support
من إعداد Proxy Host.
من العلامات التي قد تدفعك للتحقق من WebSockets أن الصفحة نفسها تعمل لكن جزءًا من التحديثات الفورية أو الاتصال الحي لا يعمل كما يجب.
12. ماذا عن التطبيقات التي تحتاج HTTPS داخليًا؟
ليست كل التطبيقات تعمل HTTP فقط.
إذا كان Backend نفسه يستقبل HTTPS، غيّر Scheme في Proxy Host إلى:
https
واستخدم Port الداخلية الصحيحة.
لكن لا تختَر HTTPS لمجرد أن المستخدم الخارجي يستعمل HTTPS.
الـScheme هنا تصف الاتصال بين Nginx Proxy Manager والـBackend، وليس الاتصال بين Browser وNginx Proxy Manager.
13. Domain واحدة أم Subdomain لكل تطبيق؟
للخدمات المستقلة، استخدام Subdomain منفصل غالبًا يجعل التنظيم أسهل.
مثلًا:
photos.example.com
cloud.example.com
automation.example.com
status.example.com
كل Subdomain يمكن أن تكون Proxy Host مستقلة وتشير إلى تطبيق مختلف.
وهذا أوضح عادة من جعل المستخدم يدخل:
example.com:2283
example.com:8080
example.com:5678
14. هل يمكن استخدام Domain الرئيسية؟
نعم.
يمكن إنشاء Proxy Host لـ:
example.com
أو:
www.example.com
ثم توجيهها إلى Web Application المناسبة.
الموضوع لا يعتمد على كون العنوان Domain رئيسية أو Subdomain؛ المهم أن DNS تشير إلى Nginx Proxy Manager وأن Proxy Host مطابقة للاسم المطلوب.
15. لا تكشف Ports التطبيقات للعالم دون حاجة
إذا كان التطبيق يستخدم:
3000
ولا يحتاج أحد إلى الوصول إليه مباشرة من الإنترنت، فلا توجد فائدة من نشر:
3000:3000
على Public Interface لمجرد أن التطبيق يحتاج Port داخليًا.
يمكن أن يبقى التطبيق داخل Docker Network، وتكون Nginx Proxy Manager هي المدخل العام عبر 80 و443.
هذا لا يحل كل مسائل Security وحده، لكنه يقلل الخدمات المكشوفة مباشرة.
16. لا تجعل Port 81 صفحة عامة بلا داعٍ
Port 81 هي لوحة إدارة وليست خدمة موجهة للزوار.
إذا كانت بيئتك تسمح، قيّد الوصول إليها بواسطة Firewall أو VPN أو شبكة إدارة موثوقة.
واستخدم بيانات دخول قوية.
الشخص الذي يحصل على وصول إداري إلى Reverse Proxy قد يستطيع تغيير طريقة وصول المستخدمين إلى عدة خدمات، لذلك لوحة الإدارة تستحق حماية حقيقية.
17. أضفت التطبيق إلى Network بعد تشغيله، هل يجب إعادة بنائه؟
يمكن ربط Container موجودة مؤقتًا بشبكة بواسطة:
docker network connect proxy CONTAINER_NAME
لكن الأفضل على المدى الطويل كتابة Network داخل Compose نفسها.
السبب أن الإعداد يصبح جزءًا من تعريف التطبيق، ويمكن إعادة بناء Container لاحقًا دون تذكر خطوة يدوية نفذتها قبل أشهر.
18. تأكد أن Nginx Proxy Manager ترى التطبيق
يمكن فحص الـNetwork:
docker network inspect proxy
يجب أن تجد Containers المطلوبة مرتبطة بها.
ويمكن كذلك تجربة الاتصال من داخل Container الخاصة بـNginx Proxy Manager باستخدام أدوات مناسبة متوفرة في البيئة، لكن غالبًا البداية الأسهل هي التأكد من اسم الخدمة والـPort والـNetwork.
19. خطأ 502 Bad Gateway ماذا يعني؟
ظهور Nginx Proxy Manager نفسها ثم:
502 Bad Gateway
يعني غالبًا أن الطلب وصل إلى Reverse Proxy، لكن المشكلة أصبحت في الوصول إلى Backend.
راجع:
- Forward Hostname.
- Forward Port.
- Scheme: HTTP أم HTTPS.
- هل Container تعمل.
- هل الخدمتان على Network مشتركة.
- هل التطبيق يستمع فعلًا على الـPort التي كتبتها.
20. الموقع يفتح لكن يعيد توجيهي إلى localhost
بعض البرامج تحتاج أن تعرف Public URL التي ستعمل عليها.
قد تجد إعدادًا مثل:
APP_URL=https://app.example.com
أو:
BASE_URL=https://app.example.com
أو متغيرات مشابهة تختلف من تطبيق إلى آخر.
إذا كان التطبيق يعتقد أن عنوانه:
http://localhost:3000
قد ينشئ Redirects أو Links خاطئة رغم أن Nginx Proxy Manager نفسها مضبوطة بصورة صحيحة.
21. التطبيق لا يعرف أن المستخدم دخل عبر HTTPS
عند وجود Reverse Proxy، يرى Backend أحيانًا اتصالًا داخليًا HTTP بينما المستخدم الخارجي دخل عبر HTTPS.
تطبيقات كثيرة تفهم Headers المرسلة من Reverse Proxy تلقائيًا، لكن بعضها يحتاج إلى إعداد مثل Trust Proxy أو Trusted Proxies.
إذا ظهرت Redirect Loop أو Cookies لا تعمل أو روابط HTTP غير متوقعة، راجع Documentation الخاصة بالتطبيق لمعرفة إعداد Reverse Proxy المطلوب.
22. لا تستخدم Advanced Configuration لمجرد أنها موجودة
Nginx Proxy Manager تسمح بإضافة إعدادات Nginx متقدمة.
لكن ابدأ بالإعداد العادي.
استخدم Custom Configuration فقط عندما يكون لديك سبب واضح، مثل Header معينة أو Timeout خاص أو متطلبات موثقة للتطبيق.
نسخ إعدادات عشوائية من عدة Tutorials قد يخلق مشكلة يصعب تشخيصها لاحقًا.
23. رتّب أسماء Containers
عندما يصبح لديك عشرة أو عشرون تطبيقًا، أسماء مثل:
app-1
container-new
test-final
server2
ستصبح مزعجة.
استخدم أسماء واضحة للخدمات في Compose.
مثلًا:
immich-server
nextcloud
n8n
vaultwarden
عندما تدخل إلى Nginx Proxy Manager بعد ستة أشهر ستعرف فورًا إلى أين تشير كل Proxy Host.
24. Backup لـNginx Proxy Manager
بعد أن تصبح Nginx Proxy Manager بوابة لعدة خدمات، إعداداتها تصبح مهمة.
في المثال الذي استخدمناه، البيانات موجودة داخل:
./data
./letsencrypt
أدخلها ضمن خطة Backup الخاصة بالـServer.
كذلك احتفظ بملف:
compose.yml
لأن وجود البيانات وحدها دون معرفة طريقة تشغيل Container يزيد وقت الاستعادة بلا داعٍ.
25. تحديث Nginx Proxy Manager
قبل Update مهمة، خذ Backup.
ثم من مجلد Compose يمكن عادة تحديث Image وتشغيل النسخة الجديدة:
docker compose pull
docker compose up -d
وبعدها:
docker compose ps
docker compose logs --tail=100
ثم جرّب أكثر من Domain، لا تكتفِ بفتح لوحة الإدارة.
ترتيب إضافة أي تطبيق جديد بعد ذلك
بعد تجهيز Nginx Proxy Manager مرة واحدة، تصبح إضافة برامج Docker الجديدة عملية واضحة:
- شغّل التطبيق.
- أضفه إلى Network المشتركة.
- أنشئ DNS Record للـSubdomain.
- أضف Proxy Host.
- اكتب اسم Container والـPort الداخلية.
- اختبر HTTP.
- فعّل SSL.
- اختبر التطبيق من خارج الـServer.
وبهذا لا تحتاج إلى حفظ قائمة مثل:
الصور = 2283
الأتمتة = 5678
التطبيق = 3000
الإدارة = 8080
كل خدمة تحصل على اسم واضح وHTTPS، بينما تبقى تفاصيل Ports الداخلية خلف Reverse Proxy.
تريد تشغيل تطبيقات Docker على Server تعمل باستمرار؟
إذا كنت ستستخدم Nginx Proxy Manager لتشغيل عدة تطبيقات وربطها بدومينات خاصة، يمكنك الاطلاع على باقات VPS Linux واختيار الموارد المناسبة لبيئتك.