NoctisNode
← أدلةالاستضافة الذاتية2026-10-239 دقائق

Caddy كـ Reverse Proxy لـ Docker: إعداد Compose مع HTTPS تلقائي

شغّل Caddy كـ reverse proxy لـ Docker: حزمة compose واحدة، وشبكة مشتركة، وreverse_proxy إلى أسماء الخدمات، وHTTPS تلقائي، ومتى تفيد تسميات caddy-docker-proxy.

باختصار: شغّل Caddy في حاوية خاصة به تنشر المنفذين 80 و443، واربطه هو وحاويات تطبيقاتك بشبكة Docker مشتركة واحدة، ووجّه `reverse_proxy` إلى اسم كل خدمة ومنفذها الداخلي (مثلاً `reverse_proxy app:3000`). يحلّ Caddy الاسم عبر DNS المدمج في Docker ويحصل تلقائياً على شهادة TLS لكل عنوان موقع.

يعرض هذا الدليل أولاً طريقة Caddyfile العادية، ثم البديل caddy-docker-proxy المعتمد على التسميات، ويشرح متى يناسب كل منهما على VPS واحد. إن كنت تشغّل Caddy مباشرة على المضيف بدلاً من Docker، فراجع دليل Caddy كـ reverse proxy الأساسي.

كيف تترابط الأجزاء

حاوية Caddy وحدها تنشر منافذ إلى العالم الخارجي. كل حاوية خلفية تنضم إلى شبكة bridge معرّفة من المستخدم (تسمى هنا `web`) وتكشف منفذها على تلك الشبكة فقط. خادم DNS المدمج في Docker، المتاح على الشبكات المعرّفة من المستخدم، يتيح لـ Caddy الوصول إلى `app:3000` باسم الخدمة أو الحاوية، فلا تحتاج أبداً إلى كتابة عناوين IP للحاويات تتغير مع كل إعادة إنشاء.

إبقاء الخلفيات غير منشورة أهم مما يبدو: يكتب Docker قواعد iptables الخاصة به، لذا فإن منفذاً منشوراً بـ `ports:` قد يكون قابلاً للوصول من الإنترنت حتى لو قال ufw إنه محجوب. استخدم `expose:` أو لا تربط أي منفذ إطلاقاً لكل ما يجب أن يكون خلف البروكسي.

المكوّنالدورمنشور على المضيف؟
حاوية caddyإنهاء TLS، التوجيه حسب اسم المضيف، إعادة التوجيه من HTTP إلى HTTPSنعم: 80/tcp و443/tcp و443/udp
شبكة webشبكة bridge مشتركة مع DNS مدمج لأسماء الخدماتلا
حاويات التطبيقاتخدماتك (تطبيقات ويب، واجهات API، لوحات تحكم)لا، يمكن الوصول إليها عبر Caddy فقط
وحدة التخزين caddy_dataالشهادات، المفاتيح الخاصة، حساب ACMEلا، لكن يجب أن تبقى دائمة

خطوة بخطوة: Caddyfile عادي مع docker compose

  1. 01.وجّه سجل A (وسجل AAAA إن كنت تستخدم IPv6) لكل اسم مضيف إلى الـ VPS قبل تشغيل Caddy، وإلا سيفشل إصدار الشهادة.
  2. 02.أنشئ الشبكة المشتركة مرة واحدة: `docker network create web`.
  3. 03.أنشئ `/opt/proxy/compose.yaml` و`/opt/proxy/Caddyfile` كما هو موضح أدناه، ثم شغّل `docker compose up -d` في `/opt/proxy`.
  4. 04.اربط كل حزمة تطبيق بالشبكة الخارجية `web` وشغّلها بالأمر `docker compose up -d`.
  5. 05.راقب إصدار الشهادة الأولى بالأمر `docker compose logs -f caddy` في `/opt/proxy`.
  6. 06.بعد تعديل Caddyfile، أعد التحميل من دون توقف: `docker compose exec -w /etc/caddy caddy caddy reload`.
# /opt/proxy/compose.yaml
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"   # HTTP/3
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data      # certificates and ACME account keys
      - caddy_config:/config
    networks:
      - web

volumes:
  caddy_data:
  caddy_config:

networks:
  web:
    external: true

اربط تطبيقاً واكتب Caddyfile

كل حزمة تطبيق تعلن الشبكة الخارجية نفسها. يصبح اسم الخدمة هو اسم المضيف الذي يتصل به Caddy. وحدة التخزين `caddy_data` هي التي يجب ألا تفقدها أبداً: حذفها يجبر Caddy على طلب كل الشهادات من جديد، ما قد يصطدم بحدود معدل ACME.

# /opt/app/compose.yaml
services:
  app:
    image: ghcr.io/example/app:latest
    restart: unless-stopped
    expose:
      - "3000"        # reachable on the network, NOT published on the host
    networks:
      - web

networks:
  web:
    external: true

# /opt/proxy/Caddyfile
{
	email [email protected]
}

app.example.com {
	reverse_proxy app:3000
}

grafana.example.com {
	reverse_proxy grafana:3000
}

api.example.com {
	reverse_proxy api-1:8080 api-2:8080 {
		lb_policy round_robin
		health_uri /healthz
		health_interval 10s
	}
}

خلفيات Caddy: الخوادم الخلفية وموازنة الحمل وفحوص السلامة

بمصطلحات Caddy، الخلفية هي upstream لتوجيه `reverse_proxy`. يمكنك إدراج عدة خوادم خلفية في توجيه واحد، واختيار `lb_policy` مثل `round_robin` أو `least_conn` أو `ip_hash`، وإضافة فحوص سلامة نشطة بـ `health_uri` بحيث تخرج الحاويات المعطلة من التناوب. والفحوص السلبية (`fail_duration`، `max_fails`) مفيدة أيضاً عندما لا يملك التطبيق نقطة نهاية للسلامة.

يضبط Caddy افتراضياً `X-Forwarded-For` و`X-Forwarded-Proto` و`X-Forwarded-Host` على الطلبات الممرَّرة. اضبط تطبيقك ليثق بنطاق شبكة البروكسي حتى يرى عنوان IP الحقيقي للعميل ويبني روابط `https://`. تعمل WebSockets وgRPC عبر `reverse_proxy` من دون إعدادات إضافية؛ ولـ gRPC بنص غير مشفر استخدم `reverse_proxy h2c://service:50051`.

تسميات بدلاً من Caddyfile: caddy-docker-proxy

من يبحث عن «مدير بروكسي لـ Caddy» يريد عادةً ما يقدمه Nginx Proxy Manager: تضيف حاوية فتحصل على اسم مضيف وشهادة من دون تعديل ملف مركزي. لا يملك Caddy واجهة رسومية رسمية، لكن المشروع المجتمعي caddy-docker-proxy (github.com/lucaslorentz/caddy-docker-proxy) يولّد Caddyfile من تسميات الحاويات ويعيد تحميل Caddy عند بدء الحاويات أو إيقافها.

يحتاج إلى صلاحية قراءة مقبس Docker، وهو ما يعادل فعلياً صلاحيات root على المضيف. اربطه للقراءة فقط، وأبقِ صورة البروكسي محدّثة، وفضّل Caddyfile العادي إن كنت تشغّل عدداً قليلاً من الخدمات.

services:
  caddy:
    image: lucaslorentz/caddy-docker-proxy:ci-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - CADDY_INGRESS_NETWORKS=web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - caddy_data:/data
    networks:
      - web

  whoami:
    image: traefik/whoami
    networks:
      - web
    labels:
      caddy: whoami.example.com
      caddy.reverse_proxy: "{{upstreams 80}}"

volumes:
  caddy_data:

networks:
  web:
    external: true

Caddyfile عادي مقابل caddy-docker-proxy

Caddyfile عاديتسميات caddy-docker-proxy
مكان الإعداداتملف واحد تديره بالإصدارات في gitتسميات موزعة على ملفات compose
الوصول إلى مقبس Dockerغير مطلوبمطلوب (حساس أمنياً)
خدمة جديدةعدّل Caddyfile وشغّل `caddy reload`أضف التسميات وشغّل الحاوية
الصورةالصورة الرسمية `caddy:2`صورة مجتمعية مبنية على Caddy
تصحيح الأخطاءاقرأ الملف مباشرةافحص الإعدادات المولّدة في السجلات
الأنسب لـإعدادات VPS صغيرة ومستقرةخدمات كثيرة قصيرة العمر أو كثيرة التغيير

تشغيله على VPS

على VPS من NoctisNode بتقنية KVM تحصل على صلاحيات root كاملة وعنوان IPv4 مخصص، لذا فإن نشر المنفذين 80 و443 من حاوية Caddy واحدة وإخفاء كل ما عداها أمر مباشر. خطة Wisp (1 vCPU، 1 GB RAM) تكفي لـ Caddy مع حاويتين خفيفتين؛ والحزم الأثقل تناسبها Pulse أو Umbra. تفاصيل إصدار الشهادات وأنماط الفشل مشروحة في كيف يعمل HTTPS التلقائي في Caddy، وتمرير TCP الخام أو SSH في تمرير TCP وSSH عبر Caddy. أحكم SSH على المضيف عبر دليل تحصين SSH.

الأسئلة الشائعة

Qكيف أجعل Caddy يعمل كـ reverse proxy لحاوية Docker؟

Aضع Caddy والحاوية على شبكة Docker واحدة معرّفة من المستخدم واستخدم `reverse_proxy service-name:port` في Caddyfile. لا تستخدم `localhost`، لأنه داخل حاوية Caddy يشير إلى Caddy نفسه.

Qلماذا يعيد Caddy الخطأ 502 Bad Gateway لحاويتي؟

Aعادةً لأن الحاويات ليست على شبكة مشتركة، أو المنفذ خاطئ (استخدم المنفذ الداخلي للحاوية، لا منفذاً منشوراً على المضيف)، أو التطبيق يستمع على 127.0.0.1 فقط داخل حاويته. اجعل التطبيق يرتبط بـ 0.0.0.0 وافحص `docker network inspect web`.

Qهل استخدام caddy-docker-proxy آمن؟

Aيعمل جيداً، لكنه يتطلب مقبس Docker الذي يمنح تحكماً يعادل root على المضيف. اربطه للقراءة فقط، وأبقِ الصورة محدّثة، وتجنب كشف نقطة نهاية الإدارة في Caddy.

Qأين يخزن Caddy الشهادات في Docker؟

Aفي `/data` داخل الصورة الرسمية، لذا اربط وحدة تخزين مسمّاة هناك. فقدانها يعني إعادة إصدار كل شهادة وربما الاصطدام بحدود معدل ACME.

Qهل يوجد مدير بروكسي لـ Caddy بواجهة ويب؟

Aلا يملك Caddy نفسه واجهة ويب رسمية؛ يُضبط عبر Caddyfile أو JSON أو واجهة API الإدارية. وتوفر أدوات معتمدة على التسميات مثل caddy-docker-proxy سير عمل مشابهاً: أضف حاوية وانطلق.

Caddy كـ Reverse Proxy لـ Docker: إعداد Compose مع HTTPS تلقائي · NoctisNode