لماذا البروكسي العكسي ضروري مع Docker
بشكل افتراضي، تستمع كل حاوية Docker على منفذ عشوائي: Nextcloud على المنفذ 8080، وGitea على المنفذ 3000، وVaultwarden على المنفذ 8200. لا يمكنك عرض عشرة منافذ مباشرةً في بيئة الإنتاج. يحل البروكسي العكسي هذه المشاكل الثلاث دفعةً واحدة: يصبح نقطة الدخول العامة الوحيدة، ويوجّه حركة المرور بناءً على اسم المضيف، ويتولى إنهاء TLS. النتيجة: app1.your-domain.com وapp2.your-domain.com تشيران كلتاهما إلى المنفذ 443 لخادمك، والبروكسي يعرف إلى أي حاوية يُعيد توجيه كل طلب.
ما يمنحك إياه البروكسي العكسي عملياً
- إنهاء TLS مركزي — أداة واحدة تحصل على شهادات Let's Encrypt وتجدّدها لجميع نطاقاتك تلقائياً دون أي خطوات يدوية
- توجيه حسب اسم المضيف —
git.your-domain.comيذهب إلى Gitea، وcloud.your-domain.comيذهب إلى Nextcloud دون أي تعارض في المنافذ - جدار حماية مُبسَّط — المنفذان 80 و443 فقط مفتوحان للعموم، وجميع منافذ Docker الداخلية تبقى غير متاحة من الخارج
- إعادة توجيه HTTP إلى HTTPS تلقائياً — يُعاد توجيه كل حركة المرور غير المشفرة توجيهًا دائمًا (301 أو 308 حسب الأداة) دون إعداد يدوي داخل كل تطبيق
- مراقبة مركزية — سجلات الوصول والأخطاء لجميع تطبيقاتك مجمّعة في مكان واحد لتسهيل تشخيص المشكلات
المتطلبات المشتركة للحلول الثلاثة
قبل اختيار أحد هذه البروكسيات الثلاثة وتثبيته، تأكد من أن خادم VPS الخاص بك يستوفي بعض الشروط الأساسية. يجب تثبيت Docker وDocker Compose (يُنصح بالإصدار Compose V2، أي الأمر docker compose بدون شرطة). يجب أن تشير سجلات DNS إلى عنوان IP العام لخادمك قبل طلب الشهادة — إذ يتحقق Let's Encrypt من DNS أثناء التحقق HTTP-01، وقد يؤدي خطأ في هذه المرحلة إلى حدّ معدل (rate limit) يمنع محاولاتك لمدة ساعة تقريبًا. يجب أن يكون المنفذان 80 و443 على خادمك حرّين: تحقق بالأمر ss -tlnp | grep -E ':80|:443' من عدم وجود خدمة أخرى تشغلهما. أخيرًا، أنشئ شبكة Docker مخصصة للبروكسي — docker network create proxy — تربط بها كل حاوية يجب أن يصل إليها البروكسي.
جدول المقارنة: Caddy مقابل Traefik مقابل Nginx Proxy Manager
مرّر الجدول أفقيًا
| المعيار | Caddy | Traefik | Nginx Proxy Manager |
|---|---|---|---|
| سهولة الإعداد | ⭐⭐⭐⭐⭐ بسيط جداً | ⭐⭐⭐ متوسط | ⭐⭐⭐⭐⭐ بسيط جداً |
| TLS تلقائي (Let's Encrypt) | ✅ أصيل، بدون إعداد | ✅ عبر ACME | ✅ عبر الواجهة الرسومية |
| تكامل Docker | يدوي (وسوم أو إعداد) | ✅ وسوم أصيلة | ✅ عبر GUI |
| طريقة الإعداد | ملف Caddyfile مقروء | وسوم Docker + YAML | واجهة رسومية |
| إعادة التحميل بدون انقطاع | ✅ عبر `caddy reload` | ✅ تلقائي | ✅ تلقائي |
| لوحة تحكم/واجهة ويب | ❌ لا | ✅ لوحة تحكم مدمجة | ✅ واجهة كاملة |
| استهلاك الذاكرة | منخفض (ملف Go تنفيذي واحد) | منخفض (ملف Go تنفيذي واحد) | أعلى (Nginx + تطبيق Node.js) |
| الأنسب لـ | مشاريع فردية/فرق صغيرة | الخدمات المصغرة، CI/CD | المبتدئون، الفرق المختلطة |
Caddy: الخيار الافتراضي لمعظم الحالات
رسّخ Caddy مكانته بوصفه الخيار الأبسط للمطورين الذين يستضيفون ما بين تطبيقين وعشرة تطبيقات على خادم VPS. فلسفته جذرية: TLS مفعَّل افتراضيًا لأي نطاق صالح، دون أي خيار يجب تفعيله أو متغير يجب تعريفه. ملف الإعداد Caddyfile مقروء عن قصد، قريب من اللغة الطبيعية، ويمكن أن يقتصر على نحو عشرة أسطر في حالة استخدام شائعة. Caddy مكتوب بلغة Go ويضم عميل ACME خاصًا به: يتصل بـ Let's Encrypt مباشرةً، ويخزّن الشهادات في دليل بياناته، ويجدّدها تلقائيًا قبل انتهاء صلاحيتها. وعلى خلاف تثبيت Nginx التقليدي الذي يعتمد غالبًا على certbot كخدمة منفصلة، لا يحتاج Caddy إلى أي تبعية خارجية لإدارة TLS. استهلاك الذاكرة يبقى منخفضًا في وضع الراحة، ما يجعله مناسبًا تمامًا لخوادم VPS المبتدئة بذاكرة 1 أو 2 غيغابايت. العيب الحقيقي الوحيد في Caddy: الاكتشاف التلقائي لحاويات Docker ليس مدمجًا. وللتغلب على ذلك، تُستخدم إما الإضافة caddy-docker-proxy أو إعداد ثابت في ملف Caddyfile.
نشر Caddy كبروكسي عكسي لـ Docker
إنشاء شبكة Docker المشتركة
أولاً، أنشئ الشبكة التي ستشترك فيها Caddy وتطبيقاتك:
docker network create proxy. تتيح هذه الشبكة المعزولة لـ Caddy الوصول إلى حاوياتك بالاسم دون كشف منافذها على المضيف.كتابة ملف Caddyfile
أنشئ ملف
Caddyfileفي جذر مشروعك. لعرض تطبيق على app.your-domain.comإلى حاوية باسم myappتستمع على المنفذ 3000: app.your-domain.com { reverse_proxy myapp:3000 }. يحصل Caddy على الشهادة تلقائياً عند أول تشغيل.كتابة ملف docker-compose.yml لـ Caddy
أنشئ
docker-compose.ymlمع خدمة Caddy: ارفع Caddyfileللقراءة فقط، احفظ بيانات TLS في حجم مسمى، انشر المنفذين 80 و443، وأضف Caddy إلى شبكة proxyالمُعلَنة خارجية.ربط تطبيقاتك بشبكة البروكسي
في ملف
docker-compose.ymlلكل تطبيق، أضف شبكة proxyكشبكة خارجية وتوقف عن كشف المنافذ على المضيف (استخدم exposeبدلاً من ports).التشغيل والتحقق
شغّل Caddy بـ
docker compose up -d، ثم تابع السجلات بـ docker compose logs -f caddy. يجب أن ترى certificate obtained successfullyلكل نطاق. اختبر بـ curl -I https://app.your-domain.com.إضافة تطبيق جديد
لكل تطبيق جديد، أضف كتلة في
Caddyfile، أعد تحميل Caddy بدون انقطاع بـ docker exec caddy caddy reload --config /etc/caddy/Caddyfile، وأضف الحاوية الجديدة إلى شبكة proxy.
Traefik: متى تختار الاكتشاف التلقائي للخدمات
يتألق Traefik في السياقات التي يتغير فيها عدد الخدمات باستمرار: بيئات CI/CD التي تنشئ الحاويات وتحذفها مع كل نشر، ومعماريات الخدمات المصغرة التي تضم أكثر من خمس خدمات مستقلة، أو الفرق التي ينشر فيها كل مطور حزمه الخاصة دون المساس بإعداد مركزي. آلية الاكتشاف التلقائي عبر تسميات Docker هي ميزته الرئيسية: عند تشغيل حاوية بالتسميات الصحيحة (traefik.http.routers.myapp.rule=Host("app.your-domain.com"))، يكتشفها Traefik فورًا ويُنشئ المسار ويطلب شهادة TLS دون أن تحتاج إلى تعديل إعداده. يتضمن Traefik أيضًا لوحة تحكم ويب تعرض في الوقت الفعلي جميع الموجّهات والخدمات والوسائط (middlewares) النشطة. في المقابل، منحنى التعلم أكثر حدة: الوسائط ونقاط الدخول وصيغة التسميات قد تربك المبتدئين، وخطأ إملائي في تسمية واحدة قد يجعل تطبيقًا غير متاح دون أي رسالة واضحة.
نشر Traefik مع اكتشاف Docker التلقائي
إنشاء ملف الإعداد الثابت
أنشئ
traefik.ymlبنقاط الدخول، فعّل موفر Docker، اضبط محلل ACME بعنوان بريدك لـ Let's Encrypt، وفعّل لوحة التحكم في الوضع الآمن.تشغيل Traefik مع Docker Compose
في
docker-compose.ymlلـ Traefik، ارفع مقبس Docker للقراءة فقط (/var/run/docker.sock:/var/run/docker.sock:ro)، ارفع traefik.yml، احفظ الشهادات في حجم، وانشر المنفذين 80 و443.إضافة التسميات إلى حاوياتك
على كل خدمة تريد عرضها، أضف تسميات Traefik:
traefik.enable=true، قاعدة الموجّه، نقطة الدخول، محلل TLS، ومنفذ الخدمة الداخلي.التحقق من لوحة التحكم
ادخل إلى لوحة تحكم Traefik وتحقق من أن موجّهك يظهر باللون الأخضر دون أخطاء. إن كان الموجّه غائباً، تحقق من وجود التسمية
traefik.enable=true.
أمان حرج: لا ترفع مقبس Docker (/var/run/docker.sock) بدون قيود في بيئة متعددة المستخدمين — أي شخص يمكنه الكتابة في هذا المقبس يمكنه السيطرة الكاملة على المضيف. الرفع للقراءة فقط (ro) لا يكفي: فهو يحمي ملف المقبس لا واجهة Docker API. في الإنتاج، ضع بروكسي مقبس مثل docker-socket-proxy بين Traefik والخادم، مقتصرًا على طلبات القراءة.
Nginx Proxy Manager: الخيار بدون ملفات إعداد
Nginx Proxy Manager (NPM) هو الخيار الواضح لمن لا يرتاح لملفات الإعداد في سطر الأوامر. تتيح واجهته الرسومية إنشاء مضيف بروكسي ببضع نقرات: تُدخل اسم النطاق وعنوان الحاوية الهدف، وتفعّل خياري «Force SSL» و«HTTP/2 Support»، ثم تنقر على «Save» — وهذا كل شيء. يتولى NPM الباقي، بما في ذلك طلب شهادة Let's Encrypt. تتيح الواجهة أيضًا إدارة عدة مستخدمين بصلاحيات مختلفة، وإضافة قوائم التحكم في الوصول، وإعداد عمليات إعادة التوجيه. في المقابل، يشغّل NPM إلى جانب Nginx تطبيق Node.js وقاعدة بيانات لتخزين إعداداته (SQLite افتراضيًا، وMariaDB أو MySQL اختياريًا)، مما يجعله أكثر استهلاكًا للذاكرة من Caddy. يناسب NPM تمامًا الفرق المختلطة بين التقنيين وغير التقنيين، أو الحالات التي يحتاج فيها أشخاص غير مدير النظام الرئيسي إلى إدارة النطاقات.
استكشاف الأخطاء: الأخطاء الأكثر شيوعاً
تندرج غالبية المشكلات في أربع فئات. أولًا، حدود معدل Let's Encrypt: إذا أعدت تشغيل حزمتك عدة مرات أثناء الاختبار بالنطاق نفسه، فقد تستنفد حد خمس شهادات لمجموعة الأسماء نفسها خلال سبعة أيام. الحل: استخدم بيئة الاختبار (staging) لدى Let's Encrypt (acme_ca https://acme-staging-v02.api.letsencrypt.org/directory في Caddy) لاختباراتك ثم انتقل إلى الإنتاج. ثانيًا، تعارض المنافذ: إذا كان المنفذ 80 أو 443 مشغولًا بخادم Apache أو Nginx على المضيف، فلن يبدأ البروكسي في Docker. حدّد العملية بالأمر ss -tlnp | grep :80 وأوقفها. ثالثًا، أخطاء شبكة Docker: تحقق من أن البروكسي والحاوية الهدف على الشبكة نفسها بالأمر docker network inspect proxy. رابعًا، بالنسبة إلى Traefik، الأخطاء الإملائية في التسميات: فعّل سجلات DEBUG (log: { level: DEBUG } في traefik.yml، أو --log.level=DEBUG إذا كان Traefik مُعدًّا عبر سطر الأوامر).
ملخص: أي بروكسي لأي ملف شخصي
- مطور فردي، 2 إلى 5 تطبيقات — Caddy: إعداد بسيط، TLS تلقائي، جاهز في أقل من عشر دقائق
- فريق DevOps، خدمات مصغرة، CI/CD — Traefik: اكتشاف تلقائي عبر التسميات، لوحة مراقبة
- مستخدم غير تقني أو فريق مختلط — Nginx Proxy Manager: واجهة رسومية بديهية، لا ملفات للتحرير
- VPS ذو ذاكرة محدودة — Caddy أو Traefik: تجنب NPM الأكثر استهلاكًا للذاكرة
- انتقال تدريجي من Nginx — Caddy: يمكن تعلم صيغته في ساعة
الخلاصة: ابدأ بـ Caddy وطوّر عند الحاجة
لغالبية العظمى من المضيفين الذاتيين الذين يديرون تطبيقات Docker على خادم VPS، يعد Caddy نقطة انطلاق ممتازة: بسيط وخفيف ويتولى TLS دون إعداد إضافي. إذا نمت بنيتك التحتية إلى أكثر من خمس خدمات مع نشر متكرر وآلي، يصبح Traefik أكثر ملاءمة.