لماذا تعتني ببروكسيك العكسي على VPS
على VPS، خادم الويب الأمامي هو القطعة التي تنسّق كل شيء: يُنهي TLS، ويوزّع حركة المرور على حاوياتك (التطبيق، منصة Git، خادم الوسائط، LLM)، ويقدّم الملفات الثابتة، ويطبّق ترويسات الأمان. وإذا أُحسِن اختياره، يبسّط جذريًا تفعيل HTTPS على جميع نطاقاتك الفرعية. يحصل Caddy على شهادات Let's Encrypt ويجدّدها تلقائيًا، من دون إعداد، عبر ملف Caddyfile مقروء من بضعة أسطر. أما Nginx، مرجع السوق، فيقدّم تحكّمًا دقيقًا للغاية (التخزين المؤقت، قواعد إعادة الكتابة، موازنة الحِمل، تحديد المعدل) لكنه يتطلّب إدارة يدوية للشهادات أو عبر Certbot. يقابل الخيار بين الأتمتة الحديثة والسيطرة الكاملة المُختبَرة.
ما الذي تقدّمه واجهة أمامية جيدة لـ VPS الخاص بك
- إنهاء TLS مركزي لجميع نطاقاتك الفرعية
- بروكسي عكسي واحد نحو عدة حاويات Docker
- تقديم سريع للملفات الثابتة وضغط (gzip/brotli)
- ترويسات أمان (HSTS، CSP، X-Content-Type-Options) مُطبَّقة في المكان نفسه
- مع Caddy: شهادات Let's Encrypt تُستحصَل وتُجدَّد تلقائيًا
- مع Nginx: تخزين مؤقت وتحديد معدل وموازنة حِمل مضبوطة بدقة
- HTTP/3 وQUIC للحد من التأخير على الاتصالات الضعيفة
المتطلبات: واجهة أمامية اقتصادية
البروكسي العكسي خفيف جدًا: يعمل كل من Caddy وNginx بأريحية على 1 vCPU و512 ميغابايت إلى 1 غيغابايت من الذاكرة، حتى أمام عدة خدمات. المورد الذي يجب مراقبته هو بالأحرى عرض النطاق وعدد الاتصالات المتزامنة. تحتاج إلى نطاق ونطاقاته الفرعية تشير إلى عنوان IP الخاص بالـ VPS (سجلات A/AAAA)، والمنفذين 80 و443 مفتوحين في الجدار الناري (المنفذ 80 مطلوب للتحقق من الشهادات)، وDocker إذا وضعت البروكسي في حاوية. لا حاجة إلى GPU ولا تخزين كبير: هنا، الإعداد هو ما يصنع الفرق، لا القدرة الخام.
إعداد Caddy (أو Nginx) كبروكسي عكسي
توجيه DNS
أنشئ سجلات A (وAAAA إذا كان IPv6) لكل نطاق فرعي (app، git، media) نحو عنوان IP الخاص بالـ VPS. سيفشل التحقق من Let's Encrypt ما دام تحليل DNS غير فعّال، لذا تحقّق منه أولًا بـ dig app.yourdomain.com أو أداة عبر الإنترنت.
فتح المنفذين 80 و443
اسمح بالمنفذين 80 و443 فقط في الجدار الناري (ufw allow 80/tcp && ufw allow 443/tcp). يظل المنفذ 80 ضروريًا لتحدّي HTTP الخاص بـ Let's Encrypt ولإعادة توجيه حركة المرور تلقائيًا إلى HTTPS.
كتابة الإعداد الأساسي
مع Caddy، تكفي كتلة واحدة: app.yourdomain.com { reverse_proxy 127.0.0.1:3000 } وHTTPS تلقائي. ومع Nginx، اكتب كتلة server لكل نطاق فرعي مع proxy_pass وترويسات X-Forwarded-*، ثم احصل على الشهادة عبر Certbot: certbot --nginx -d app.yourdomain.com.
إعداد نطاقات فرعية متعددة
مع Caddy، ضع كل كتلة في نفس Caddyfile: git.yourdomain.com { reverse_proxy 127.0.0.1:3001 }. مع Nginx، أنشئ ملفًا لكل نطاق فرعي في /etc/nginx/conf.d/ وفعّله بـ ln -s. كلا الأسلوبين يتيحان إدارة عشرات الخدمات دون تكرار.
تفعيل الضغط
يفعِّل Caddy gzip افتراضيًا؛ لإضافة brotli: encode zstd br gzip في كتلة الموقع. في Nginx، أضِف إلى nginx.conf: gzip on; gzip_types text/plain text/css application/json application/javascript; gzip_min_length 256;. يُقلّص الضغطُ حجمَ ردود النصوص من 60 إلى 80% في معظم الحالات.
التشغيل وإعادة التحميل من دون انقطاع
شغِّل الخدمة (docker compose up -d أو systemctl start caddy). بعد كل تعديل، تحقّق من صحة الإعداد (nginx -t أو caddy validate) ثم أعِد التحميل السريع (nginx -s reload / caddy reload) كي لا تقطع حركة المرور أبدًا.
التحقق من الشهادات
مع Caddy، نفِّذ caddy validate --config /etc/caddy/Caddyfile لاكتشاف الأخطاء قبل إعادة التحميل، وراجع السجلات (journalctl -u caddy -f) لتأكيد إصدار الشهادة. مع Nginx + Certbot، يُدرج certbot certificates تواريخ الانتهاء، وcertbot renew --dry-run يُحاكي التجديد.
تعزيز الأمان وإعداد السجلات
فعِّل HSTS، وأخفِ إصدار الخادم (server_tokens off في Nginx، تلقائي في Caddy)، وافرض TLS 1.2+، وأضِف تحديد معدل أساسيًا. فعِّل سجلات الوصول والأخطاء، وراقب الرموز 502/504 التي تكشف حاوية نهائية غير قابلة للوصول.
بعد تشغيل البروكسي وإصدار الشهادات، تأتي خطوتان تكمّلان الأمان والأداء: الإعداد المتقدم للترويسات وتحديد المعدل، ثم إعداد المراقبة. الترتيب مهم: تحقّق أولًا من أن التوجيه الأساسي يعمل (curl -I https://app.yourdomain.com) قبل إضافة طبقات الإعداد.
الإعداد المتقدم: الأمان والضغط وHTTP/3
بعد تجهيز الأساس، ثلاثة محاور تُحسّن وضعية البروكسي العكسي بشكل ملموس.
ترويسات الأمان. طبِّق على مستوى البروكسي الترويسات التي ستُهمِلها كل خدمة خلفية: Strict-Transport-Security: max-age=31536000; includeSubDomains (HSTS)، وX-Content-Type-Options: nosniff، وX-Frame-Options: SAMEORIGIN، وContent-Security-Policy ملائمة لتطبيقك. تمركُز هذه الترويسات في البروكسي يضمن تغطيتها لجميع نطاقاتك الفرعية بإجراء واحد.
تحديد المعدل. في Caddy، تتيح وحدة rate_limit (المتوفرة عبر xcaddy build) تحديد الطلبات لكل IP. في Nginx، يكفي limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m; في http {} ثم limit_req zone=api burst=10 nodelay; في الـ location المعني لحماية واجهة برمجية من الإساءة دون تبعيات خارجية.
HTTP/3 وQUIC. يُفعِّل Caddy HTTP/3 افتراضيًا بمجرد فتح منفذ UDP 443. يدعم Nginx QUIC منذ الفرع الرئيسي (المعامل quic في كتلة listen)؛ تحقّق من الإصدار المُثبَّت بـ nginx -v قبل تفعيل التوجيه. يُقلّص HTTP/3 التأخيرَ المُدرَك على اتصالات الجوال والشبكات الهشّة، دون أي تغيير في سلوك العملاء الذين لا يدعمونه.
Caddy مقابل Nginx — جدول مقارن
| المعيار | Caddy | Nginx |
|---|---|---|
| HTTPS / الشهادات | تلقائي، بلا إعداد | يدوي أو عبر Certbot |
| صياغة الإعداد | Caddyfile، مقتضب جدًا | أكثر إسهابًا، معبِّر جدًا |
| منحنى التعلّم | منخفض | متوسط إلى مرتفع |
| تحكّم دقيق (تخزين مؤقت، إعادة كتابة، موازنة حِمل) | جيد، أحيانًا عبر إضافات | متكامل جدًا ومُختبَر |
| HTTP/3 / QUIC | مُفعَّل افتراضيًا | مدعوم (الفرع الرئيسي) |
| تحديد المعدل الأصلي | عبر وحدة xcaddy | مدمَج (`limit_req`) |
| الوحدات الديناميكية | تجميع عبر xcaddy | وحدات ديناميكية (.so) |
| استهلاك الذاكرة في الخمول | 30–50 ميغابايت تقريبًا | 20–40 ميغابايت (العمال) |
| تنسيق السجلات | JSON منظَّم افتراضيًا | نصي، قابل للضبط |
| مثالي لـ | تفعيل HTTPS سريع، نطاقات فرعية متعددة | ضبط متقدم، حركة مرور عالية |
تُغطّي خطوات النشر الإعداد المثالي. في الواقع، تعود عدة أنواع من الأخطاء بانتظام: شهادة محجوبة بشبكة وسيطة، وخدمة لاحقة لم تستجب بعد، وحاوية Docker غير قابلة للوصول من البروكسي لأن الاثنين على شبكات منفصلة. أكثر لوحة مفيدة في هذه الحالات هي سجل البروكسي (journalctl -u caddy -f أو tail -f /var/log/nginx/error.log)، مقرونًا بـ curl محليًا لعزل المشكلة.
تحديد الأعطال: الأخطاء الأكثر شيوعًا
حتى البروكسي المُعدَّ جيدًا يُنتج أخطاءً عند البدء أو تحت الحِمل. إليك الحالات الخمس الأكثر تكرارًا.
Caddy — «no certificate» خلف موازن حِمل. حين يكون Caddy خلف موازن حِمل يُنهي TLS بالفعل، لا يمكنه استقبال تحدّي HTTP-01 من Let's Encrypt ويفشل في إصدار الشهادة. الحل: استخدام تحدّي DNS-01 عبر إضافة مزوّد النطاق (مثلًا tls { dns cloudflare {env.CF_API_TOKEN} })، أو تفويض إدارة TLS بالكامل لموازن الحِمل وإجبار Caddy على عمل http:// داخليًا.
Nginx — 502 Bad Gateway (انتهاء مهلة المنبع). يدل الخطأ 502 المتواصل بعد البدء على أن الخدمة اللاحقة لا تستمع بعد أو تعطّلت. تحقّق بـ curl -v http://127.0.0.1:<port> من الخادم. إذا كانت الخدمة تبدأ ببطء، ارفع proxy_read_timeout وproxy_connect_timeout. يدل الخطأ 502 المتقطّع تحت الحِمل على نقص في اتصالات keepalive: أضِف keepalive 32; في كتلة upstream.
Caddy مع Docker — الحاوية غير قابلة للوصول. حين يعمل Caddy والخدمة الهدف في شبكات Docker منفصلة، لا يعمل reverse_proxy 127.0.0.1:3000: فـ 127.0.0.1 هو عنوان الحلقة المحلية لحاوية Caddy، لا للمضيف. الحل: وصِّل الحاويتين بنفس شبكة Docker bridge المُسمَّاة واستخدم اسم الخدمة كعنوان هدف: reverse_proxy service-name:3000.
Nginx — «too many open files» تحت الحِمل. يظهر الخطأ worker_connections are not enough أو open() failed (24: Too many open files) حين يستقبل VPS ذروة مرور. ارفع حدّ النظام (ulimit -n 65535 أو DefaultLimitNOFILE=65535 في وحدة systemd) وحاذِ worker_connections 4096; في nginx.conf. الحد الأقصى للاتصالات المتزامنة هو worker_processes * worker_connections.
Caddy — تجديد مُعاق في صمت. يجدّد Caddy في الخلفية، لكن إن كان منفذ UDP 443 مُغلَقًا بواسطة الجدار الناري، يفشل HTTP/3 وقد تُخفي السجلات السبب الحقيقي. راقب journalctl -u caddy -f قرب تواريخ التجديد (60 يومًا بعد الإصدار) واختبر التحدّي بـ caddy run --config /etc/caddy/Caddyfile --watch في المقدمة لرؤية الأخطاء بشكل فوري.
Caddy أم Nginx أم Traefik: الخيار الثالث
لبنية تحتية تضم عددًا كبيرًا من الخدمات المصغّرة Docker مع اكتشاف تلقائي للحاويات، يبرز Traefik خيارًا ثالثًا: يقرأ ملصقات Docker (traefik.http.routers.myapp.rule=Host("app.yourdomain.com")) ويُعيِّن المسارات تلقائيًا دون إعادة تحميل يدوية. العيب هو إعداده الأعقد وتوثيقه الأكثف. يبقى Caddy وNginx الخيارَين الطبيعيَّين لـ VPS بحجم معقول (1 إلى 20 خدمة)؛ يتولى Traefik ما هو أكبر، لا سيما في سياق Kubernetes أو Docker Swarm. لمقارنة شاملة بين الثلاثة، اطلع على مقال اختيار بروكسيك العكسي لـ VPS: Caddy أم Traefik أم Nginx.
الجمع بينهما بدلًا من الاختيار
إن كنت لا تزال مترددًا، فاعلم أن Caddy وNginx لا يتعارضان. نمط شائع يضع Caddy كأول واجهة أمامية لإدارة TLS تلقائيًا لجميع نطاقاتك الفرعية، ثم يترك Nginx في الخلف للتخزين المؤقت الدقيق وقواعد إعادة الكتابة لخدمة محددة. بهذا تجمع بين أتمتة الشهادات والتحكّم في الضبط، من دون اختيار طرف نهائيًا.