دليل عملي

النشر

انشر تطبيقاتك باستخدام Traefik على خادم VPS

Traefik هو وكيل عكسي وموازن أحمال أصيل السحابة (cloud-native) يكتشف حاويات Docker الخاصة بك تلقائيًا ويسند إليها المسارات وشهادات SSL دون إعادة تحميل يدوية. مَنشورًا على خادم VPS الخاص بك، يصبح نقطة الدخول الوحيدة لجميع تطبيقاتك، بتهيئة تصريحية عبر علامات (labels) Docker. يثبّت هذا الدليل الفرع v3 (الإصدار v3.7 وقت الكتابة)، مع HTTPS من Let's Encrypt، ولوحة تحكم محمية، وHTTP/3، وبرمجيات وسيطة للإنتاج، والفخاخ التي يجب معرفتها إن كنت قادمًا من Traefik v2.

11 دقيقةً للقراءةعدد الخطوات: 7
المحتويات· لماذا تضع Traefik في واجهة خادم VPS الخاص بك؟1/13
  1. 01لماذا تضع Traefik في واجهة خادم VPS الخاص بك؟
  2. 02ما يقدّمه Traefik عمليًا على خادم VPS
  3. 03المتطلبات
  4. 04انشر Traefik باستخدام Docker Compose
  5. 05برمجيات وسيطة مفيدة في الإنتاج
  6. 06خمس برمجيات وسيطة يجب معرفتها
  7. 07فعّل HTTP/3 (QUIC)
  8. 08القادم من Traefik v2: ما الذي يتعطل
  9. 09التغييرات الكاسرة في v3
  10. 10Traefik v3 أم Nginx أم Caddy أمام حاوياتك
  11. 11استكشاف الأعطال: الأخطاء الأكثر شيوعًا
  12. 12الأعراض وطرق الإصلاح
  13. 13الخطوة التالية: تقوية المكدّس

لماذا تضع Traefik في واجهة خادم VPS الخاص بك؟

عندما تشغّل عدة تطبيقات محوّلة إلى حاويات على خادم VPS نفسه، تصبح إدارة المضيفات الافتراضية (virtual hosts) في Nginx يدويًا وتجديد كل شهادة أمرًا غير قابل للإدارة بسرعة. يحل Traefik هذه المشكلة بقراءة علامات حاويات Docker الخاصة بك مباشرةً: تعلن عن مسار عند تنفيذ docker run أو في ملف docker-compose.yml، فيهيّئه Traefik أثناء التشغيل، ويولّد شهادة Let's Encrypt، ويعرضه عبر HTTPS. لا ملف تهيئة لتحريره، ولا إعادة تحميل: كل شيء ديناميكي.

يبقى Nginx خادم HTTP ممتازًا، لكن تهيئته ثابتة: كل خدمة جديدة تتطلب ملف vhost، وأمر nginx -s reload، وأداة ACME منفصلة (certbot ومهمة التجديد الخاصة به). صُمّم Traefik لبنية تتغير باستمرار، وهذه بالضبط حال خادم VPS تُضاف إليه الحاويات وتُحدَّث وتُزال كل أسبوع. وقد ثبّت الفرع v3، الصادر في أبريل 2024، دعم HTTP/3 وتصدير التتبع عبر OpenTelemetry، وشدّد صياغة قواعد التوجيه.

ما يقدّمه Traefik عمليًا على خادم VPS

  • اكتشاف تلقائي لحاويات Docker عبر مزوّد Docker (تظهر المسارات دون إعادة تشغيل)
  • شهادات SSL من Let's Encrypt تُولَّد وتُجدَّد تلقائيًا (تحديات HTTP-01 أو TLS-ALPN-01 أو DNS-01)، ويبدأ تجديدها افتراضيًا قبل 30 يومًا من انتهاء صلاحيتها
  • توجيه حسب النطاق أو المسار أو الترويسة، يُدار بالكامل عبر علامات Docker
  • لوحة تحكم ويب مدمجة لعرض الموجّهات (routers) والخدمات والبرمجيات الوسيطة (middlewares) في الوقت الحقيقي
  • برمجيات وسيطة جاهزة للاستخدام: إعادة توجيه HTTPS، والمصادقة الأساسية (basic auth)، وتحديد معدل الطلبات، وترويسات الأمان، والضغط
  • موازنة أحمال تلقائية عند توسيع خدمة إلى عدة نسخ (replicas)
  • تفعيل HTTP/3 (QUIC) على نقطة دخول بخيار واحد
  • مزوّدات أخرى غير Docker (Swarm وKubernetes وNomad والملفات) إذا توسّعت بنيتك التحتية

المتطلبات

Traefik نفسه خفيف جدًا: معالج vCPU واحد و1 غيغابايت من RAM يكفيان بوفرة للوكيل وحده، والتكلفة الإضافية تأتي من تطبيقاتك خلفه. جهّز خادم VPS يعمل بنظام Debian 12 أو Ubuntu 22.04/24.04 مع Docker Engine وإضافة Docker Compose v2 مثبَّتة (الأمر docker compose دون شرطة)، واسم نطاق تشير سجلّاته A/AAAA إلى عنوان IP الخاص بخادم VPS قبل التشغيل الأول (وإلا فلن تتمكن Let's Encrypt من التحقق من النطاق)، والمنفذين 80 و443 مفتوحين للاتصالات الواردة عبر TCP في جدار الحماية (UFW)، إضافةً إلى المنفذ 443 عبر UDP إن فعّلت HTTP/3. احتفظ بعنوان بريد إلكتروني صالح لحساب ACME. للحصول على شهادات wildcard، ستحتاج أيضًا إلى وصول API إلى مزوّد DNS الخاص بك.

انشر Traefik باستخدام Docker Compose

  1. أنشئ الشبكة والبنية الشجرية

    أنشئ شبكة Docker مشتركة سيستخدمها Traefik وتطبيقاتك، ثم مجلدًا مخصصًا يحتوي على الملف acme.json (مخزن الشهادات ومفاتيحها الخاصة):

    docker network create proxy
    mkdir -p /opt/traefik && cd /opt/traefik
    touch acme.json && chmod 600 acme.json

    أنشئ الملف قبل التشغيل الأول: إذا لم يكن المسار المربوط موجودًا، يُنشئ Docker مجلدًا مكانه ولا يعود Traefik قادرًا على الكتابة فيه. الصلاحيات 600 إلزامية: يرفض Traefik ملفًا يستطيع مستخدمون آخرون قراءته.

  2. هيّئ نقاط الدخول (entrypoints) ومحلّل ACME

    ضع هذا الملف في /opt/traefik/docker-compose.yml. يعلن نقطتَي دخول (web على :80، وwebsecure على :443)، وcertificateResolver من Let's Encrypt يُتحقَّق منه عبر تحدي HTTP، واكتشاف الحاويات عبر مقبس Docker المربوط للقراءة فقط، ولوحة التحكم:

    services:
      traefik:
        image: traefik:v3.7
        container_name: traefik
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
          - "443:443/udp"
        command:
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--providers.docker.network=proxy"
          - "--entrypoints.web.address=:80"
          - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
          - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
          - "--entrypoints.websecure.address=:443"
          - "--entrypoints.websecure.http3=true"
          - "[email protected]"
          - "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
          - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
          - "--api.dashboard=true"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
          - "./acme.json:/acme.json"
        networks:
          - proxy
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
          - "traefik.http.routers.dashboard.entrypoints=websecure"
          - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
          - "traefik.http.routers.dashboard.service=api@internal"
          - "traefik.http.routers.dashboard.middlewares=dashboard-auth"
          - "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$2y$$05$$REMPLACER_PAR_LE_HASH"
    
    networks:
      proxy:
        external: true

    الخيار exposedbydefault=false أساسي: من دونه تُنشر كل حاوية على الخادم، بما فيها قاعدة بياناتك. ثبّت الفرع (v3.7) بدلًا من latest، وتابع الإصدارات قبل الانتقال إلى إصدار فرعي جديد.

  3. افرض إعادة التوجيه من HTTP إلى HTTPS

    تُعلَن إعادة التوجيه مباشرةً على نقطة الدخول web، بالخيارين --entrypoints.web.http.redirections.entrypoint.to=websecure و...entrypoint.scheme=https الموجودين أصلًا في الملف أعلاه. هذا أبسط وأكثر أمانًا من موجّه «catch-all» مع برمجية وسيطة: تُحوَّل كل حركة المرور غير المشفّرة إلى HTTPS بإعادة توجيه دائمة، دون علامة تُكرَّر على كل خدمة، ويواصل تحدي HTTP الخاص بـ Let's Encrypt المرور عبر المنفذ 80.

  4. أمّن لوحة التحكم

    تُعرض لوحة التحكم على traefik.example.com خلف البرمجية الوسيطة basicauth المسمّاة dashboard-auth. ولّد تجزئة bcrypt (الحزمة apache2-utils على Debian/Ubuntu) مع مضاعفة علامات $، كما تشترط قيمة علامة داخل ملف Compose:

    apt install -y apache2-utils
    htpasswd -nB admin | sed -e 's/\$/\$\$/g'

    الصق النتيجة مكان admin:$$2y$$05$$REMPLACER_PAR_LE_HASH. التجزئة الملصقة بعلامات $ مفردة يقرؤها Compose كمتغيرات فتتعطل المصادقة. لا تترك أبدًا الراية --api.insecure=true في الإنتاج: فهي تنشر لوحة التحكم دون مصادقة.

  5. شغّل Traefik

    ابدأ المكدّس وتابع السجلّات:

    cd /opt/traefik
    docker compose up -d
    docker compose logs -f traefik

    يُفترض أن ترى مزوّد Docker يبدأ، ثم الموجّه dashboard يرتبط، دون أي خطأ ACME. أثناء التجارب، أضِف مؤقتًا --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory: يصدر خادم staging من Let's Encrypt شهادات لا تثق بها المتصفحات، لكنه يحميك من حد المعدل (rate limit) في بيئة الإنتاج إذا فشلت تهيئة ما مرارًا. احذف الخيار وأفرغ acme.json قبل الانتقال إلى الإنتاج.

  6. اربط تطبيقًا

    يعيش كل تطبيق في ملف docker-compose.yml خاص به، مربوطًا بشبكة proxy وموصوفًا بعلاماته:

    services:
      app:
        image: ghcr.io/example/app:1.0.0
        restart: unless-stopped
        networks:
          - proxy
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.app.rule=Host(`app.example.com`)"
          - "traefik.http.routers.app.entrypoints=websecure"
          - "traefik.http.routers.app.tls.certresolver=letsencrypt"
          - "traefik.http.services.app.loadbalancer.server.port=3000"
    
    networks:
      proxy:
        external: true

    عند تنفيذ docker compose up -d، يكتشف Traefik الحاوية ويحصل على الشهادة ويفعّل المسار في ثوانٍ، دون المساس بتهيئته الخاصة. تحدد العلامة loadbalancer.server.port المنفذ الداخلي للتطبيق، وتصبح ضرورية حين تعرض الصورة أكثر من منفذ. يجب أن يكون اسم الموجّه (app هنا) فريدًا على مستوى الخادم كله.

  7. تحقّق من الشهادة وإعادة التوجيه

    تحقّق من جهاز خارج خادم VPS:

    curl -I http://app.example.com
    curl -I https://app.example.com
    dig +short app.example.com

    يجب أن يعيد الطلب الأول إعادة توجيه دائمة نحو https://، والثاني الرمز 200 (أو رمز تطبيقك) مع شهادة Let's Encrypt صالحة، ويجب أن يعرض dig عنوان IP الخاص بالخادم. تسرد لوحة التحكم أيضًا كل موجّه مع محلّل شهادته. المنفذ 80 الذي يرفض الاتصال يشير في الغالب إلى جدار الحماية.

برمجيات وسيطة مفيدة في الإنتاج

تُعلَن البرمجية الوسيطة في Traefik عبر علامة، مرة واحدة، ثم تُربط بموجّه أو أكثر عبر traefik.http.routers.<router>.middlewares=<name1>,<name2>. لذا تعرّفها على الخدمة المعنية دون المساس بالتهيئة المركزية لـ Traefik. إليك تلك التي تفيد على كل خادم VPS تقريبًا.

خمس برمجيات وسيطة يجب معرفتها

  • BasicAuth على أداة إدارة (Adminer وFlower…): traefik.http.middlewares.adminauth.basicauth.users=admin:$$2y$$05$$...، ثم traefik.http.routers.myadmin.middlewares=adminauth. القاعدة نفسها لمضاعفة $ كما في لوحة التحكم.
  • تحديد معدل الطلبات أمام واجهة API أو نموذج: traefik.http.middlewares.ratelimit.ratelimit.average=100 و...ratelimit.period=1s و...ratelimit.burst=200 تسمح بـ 100 طلب في الثانية في المتوسط، مع دفعات تصل إلى 200. دون average يكون الحد معطّلًا.
  • ترويسات الأمان: تضع البرمجية الوسيطة headers ترويسة HSTS (stsSeconds=31536000 وstsIncludeSubdomains=true)، وX-Frame-Options: DENY (frameDeny=true)، وX-Content-Type-Options: nosniff (contentTypeNosniff=true)، دون ملف تهيئة منفصل.
  • إعادة توجيه www إلى النطاق المجرد: redirectregex مع regex=^https://www\.(.+) وreplacement=https://$${1} وpermanent=true. لا تنسَ إعلان المضيفين معًا في قاعدة الموجّه حتى تغطي الشهادة www.
  • الضغط: يفعّل traefik.http.middlewares.compress.compress=true كلًّا من gzip وBrotli وZstandard بحسب ما يقبله المتصفح، دون أي إعداد في جهة التطبيق.

للحصول على شهادة wildcard (*.example.com) وتجنّب عرض كل نطاق فرعي، انتقل من httpChallenge إلى dnsChallenge: فهو التحدي الوحيد الذي يصدر شهادة wildcard. مع Cloudflare، أعلن --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare ومرّر إلى Traefik المتغير CF_DNS_API_TOKEN، وهو رمز API مقيَّد بالصلاحيتين Zone / DNS / Edit وZone / Zone / Read. يعمل الزوج القديم CF_API_EMAIL + CF_API_KEY أيضًا، لكنه يتطلب مفتاح API العام الذي يفتح الحساب كله: فضّل الرمز. يُثبت Traefik عندها ملكية النطاق عبر سجل TXT، وهو ما يعمل حتى للخدمات غير المعروضة علنًا.

فعّل HTTP/3 (QUIC)

يفعّله ملف Compose أعلاه أصلًا: --entrypoints.websecure.http3=true على نقطة دخول TLS، ونشر المنفذ 443:443/udp. يستمع Traefik عندها عبر UDP على المنفذ نفسه الذي تستخدمه نقطة دخول TCP؛ يبدأ الاتصال دائمًا عبر TCP ثم ينتقل المتصفح إلى QUIC في الجولة التالية. شرطان: لا تُخدَم عبر HTTP/3 إلا الموجّهات المفعَّل فيها TLS، ويجب أن يسمح جدار الحماية بمرور المنفذ 443 عبر UDP (ufw allow 443/udp). إذا نشرت منفذ UDP مختلفًا عن منفذ نقطة الدخول، يعلن الخيار http3.advertisedPort المنفذ الصحيح. للتحقق، استخدم curl مبنيًّا بدعم HTTP/3: curl --http3 -I https://app.example.com.

القادم من Traefik v2: ما الذي يتعطل

يحافظ الإصدار v3 على توافق تهيئة التوجيه في v2، لكنه يغيّر الصياغة الافتراضية للقواعد ويرفض الإقلاع مع عدة خيارات أُزيلت. للترحيل دون إعادة كتابة كل شيء دفعة واحدة، أضِف --core.defaultRuleSyntax=v2 إلى تهيئة التثبيت: تستمر قواعدك القديمة في العمل، وتنقل الموجّهات واحدًا تلو الآخر إلى صياغة v3، ثم تحذف الخيار. تنبّه سجلّات Traefik إلى كل خيار مُهمَل ما زال مستخدمًا: اقرأها بعد التشغيل الأول. التغييرات التي توقع المستخدمين أكثر من غيرها:

التغييرات الكاسرة في v3

  • Swarm: لم يعد الخيار swarmMode في مزوّد Docker موجودًا، وهو يمنع الإقلاع. أصبح لـ Docker Swarm مزوّد خاص به (--providers.swarm).
  • قواعد التوجيه: يصبح Headers وHeadersRegexp على التوالي Header وHeaderRegexp، ويختفي HostHeader لصالح Host، ولم تعد معظم أدوات المطابقة تقبل إلا قيمة واحدة.
  • المسارات: لم يعد Path وPathPrefix يقرآن تعبيرًا نمطيًا ولا عنصرًا نائبًا مثل {id}، فلا يطابق مسار كهذا أي شيء بعد الآن. انتقل إلى PathRegexp الذي يتبع صياغة regexp في Go، مثل HostRegexp.
  • برمجيات وسيطة أُعيدت تسميتها أو خُفّفت: يصبح IPWhiteList باسم IPAllowList (بالخيارات نفسها)، وتفقد البرمجية الوسيطة headers الخيارات sslRedirect وsslTemporaryRedirect وsslHost وsslForceHost وfeaturePolicy.
  • Content-Type: لم يعد Traefik يخمّن نوع استجابة لم يحدد الخادم الخلفي نوعها؛ أضِف البرمجية الوسيطة ContentType إن كان تطبيق ما يعتمد على ذلك.
  • مزوّدات وأدوات مراقبة أُزيلت: تمنع Marathon وRancher v1 وTraefik Pilot ومقاييس InfluxDB v1 الإقلاع؛ ويمر التتبع (tracing) عبر OpenTelemetry وحده (لا تصدير مباشر بعد الآن إلى Jaeger أو Zipkin أو Datadog).

Traefik v3 أم Nginx أم Caddy أمام حاوياتك

مرّر الجدول أفقيًا

المعيارTraefik v3NginxCaddy 2
التهيئةعلامات Docker أو YAML أو TOML، تُطبَّق أثناء التشغيلملفات vhost ثابتة، و`nginx -s reload` عند كل تغييرCaddyfile أو واجهة JSON، وإعادة تحميل دون انقطاع
HTTPS تلقائيمدمج (ACME: HTTP-01 وTLS-ALPN-01 وDNS-01)أداة خارجية (certbot) ومهمة تجديدمدمج ومفعَّل افتراضيًا
اكتشاف الحاوياتأصيل، عبر مقبس Dockerغائب: أداة خارجية أو تحرير يدويعبر الوحدة المجتمعية caddy-docker-proxy
HTTP/3مستقر منذ v3.0 (أبريل 2024)، بخيار واحد لكل نقطة دخولتجريبي منذ nginx 1.25.0 (مايو 2023)، بتهيئة مخصصةمفعَّل افتراضيًا منذ Caddy 2.6 (سبتمبر 2022)
سهولة التعلّممتوسطة: موجّهات وخدمات وبرمجيات وسيطة يجب استيعابهامعروف للجميع، لكن HTTPS مع Docker يتطلبان أدوات إضافيةالأسرع لبضعة مواقع

استكشاف الأعطال: الأخطاء الأكثر شيوعًا

تأتي معظم أعطال Traefik من أربعة مصادر: DNS أو جدار حماية يمنعان تحقق Let's Encrypt، والملف acme.json، وشبكة Docker ناقصة، وعلامات مكتوبة بشكل خاطئ. إليك الأعراض وطرق إصلاحها:

الأعراض وطرق الإصلاح

  • لم يُحصل على الشهادة، وخطأ ACME من نوع unauthorized أو 403 في السجلّات: لا تستطيع Let's Encrypt الوصول إلى نطاقك. تحقّق من الخارج أن المنفذ 80 يستجيب (curl -I http://app.example.com) وأن DNS يشير إلى الخادم (dig +short app.example.com). خلف شبكة CDN في وضع الوكيل، فضّل dnsChallenge.
  • permissions 644 for /acme.json are too open, please use 600: يرفض المحلّل الملف. أصلح ذلك بـ chmod 600 /opt/traefik/acme.json ثم أعد تشغيل Traefik؛ يحمي هذا الفحص المفاتيح الخاصة المخزنة فيه.
  • المسار ظاهر في لوحة التحكم لكن مع 502 Bad Gateway: الحاوية ليست على شبكة proxy، أو المنفذ الداخلي خاطئ. تحقّق بـ docker inspect <container> (قسم Networks)، وأضِف الشبكة أو العلامة loadbalancer.server.port، ثم أعد إنشاء الحاوية. على حاوية مرتبطة بعدة شبكات، تزيل العلامة traefik.docker.network=proxy الالتباس.
  • علامات متجاهَلة ومسار غائب عن لوحة التحكم: تنقص العلامة traefik.enable=true (إلزامية مع exposedbydefault=false)، أو تعلن خدمتان اسم الموجّه نفسه. تشير سجلّات Traefik حينها إلى التعارض.
  • BasicAuth يرفض كلمة مرور صحيحة: علامات $ في التجزئة غير مضاعفة في ملف docker-compose.yml. في ملف Compose تصبح كل $ علامتين $$؛ أما في ملف تهيئة ديناميكية بصيغة YAML أو TOML فتُلصق التجزئة كما هي.

الخطوة التالية: تقوية المكدّس

يتولى Traefik التوجيه وTLS، لكن المكدّس الجاهز للإنتاج يتطلب أكثر من ذلك: فحوص الصحة (healthchecks)، وسياسة إعادة التشغيل، وتدوير السجلّات، وإبقاء الأسرار خارج ملف Compose، ونسخ الأحجام احتياطيًا (بما فيها acme.json). تتناول قائمة التحقق لـ Docker Compose في الإنتاج هذه النقاط واحدة تلو الأخرى. وإن كنت ما زلت مترددًا في اختيار الأداة، تساعدك مقارنة Caddy وTraefik وNginx Proxy Manager على الحسم بحسب عدد الخدمات والحاجة إلى الاكتشاف التلقائي.

أطلق Traefik في دقائق على خادم VPS Cloud من ServOrbit

اطلب خادم VPS Cloud مع Docker مثبَّت مسبقًا وانشر مكدّس Traefik الخاص بك انطلاقًا من قالب النشر. تُوجَّه تطبيقاتك عبر HTTPS تلقائيًا.