مناقشة مع Traefik 2.0

هل يمكنك مشاركة لقطات الشاشة؟

مرفق صورتان من شاشة لوحة تحكم Traefik. تظهران أن Discourse يظهر (مرتين) في الخدمة، لكن لا يوجد شيء في الموجهات. لا أعرف بالضرورة ما يعنيه ذلك في الحقيقة، لكنني لاحظت ذلك.

تعديل: أنا مستخدم جديد في Discourse، لذا لا يُسمح لي بنشر صورتين في منشور واحد، لذا سأرد بصورة أخرى.

أحتاج إلى تشغيل حاويات Docker الخاصة بي الليلة للمقارنة، وسأخبرك بذلك، أو ربما يمكن لبعض الآخرين هنا مشاركة لوحة التحكم الخاصة بهم والمقارنة

لا تحتاج إلى ذلك، من الأفضل التبديل إلى واجهة برمجة التطبيقات واستخدام Traefik v2.1، إذن:
- "traefik.http.routers.traefik_dashboard-router.service=api@internal"
راجع Endless 502 / forwarding when calling dashboard via subdomain #6123 - #5 by ldez - Traefik v2 - Traefik Labs Community Forum

هل يمكنك إزالة تعليقاتك؟

هذا يجعلها أسهل للقراءة بالنسبة لنا.
لا تقلق، قيل لي ذلك مرة واحدة أيضًا :).
أكتب تعليقاتي في سطر منفصل، حتى أتمكن من إنشاء طباعة نظيفة بسهولة باستخدام cat traefikV2.yaml | grep -v "#"

هنا لوحة التحكم الخاصة بي

  1. لوحة التحكم
  2. الموجهات HTTP
  3. خدمات HTTP
  4. وسائط HTTP الوسيطة

حسنًا، استغرقني الأمر بضعة أيام للوصول إلى هنا. لقد أعدت تكوين Traefik الخاص بي لاستخدام ملف YAML بدلاً من وضع كل شيء في docker-compose. ومع ذلك، بعد إعادة توصيل كل شيء، يبدو أنني أحصل على نفس السلوك أو سلوكًا مشابهًا — فأنا أحصل على خطأ 404 في نطاقى، وفي لوحة تحكم Traefik أرى مدخلات تحت Services وrouters لـ discourse، لكن لا يوجد شيء تحت routers.

Traefik docker-compose
version: '3'

services:
  traefik:
    image: traefik:v2.0
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`monitor.example.com`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=user:redacted"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`monitor.example.com`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=http"
      - "traefik.http.routers.traefik-secure.service=api@internal"

networks:
  proxy:
    external: true
Traefik data/traefik.yml
api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  http:
    acme:
      email: nick@innomadic.com
      storage: acme.json
      httpChallenge:
        entryPoint: http
containers/app.yml
templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"

expose:

params:
  db_default_text_search_config: "pg_catalog.english"

  db_shared_buffers: "128MB"



env:
  LANG: en_US.UTF-8

  UNICORN_WORKERS: 2

  DISCOURSE_HOSTNAME: forum.example.com


  DISCOURSE_DEVELOPER_EMAILS: 'info@example.com'

  DISCOURSE_SMTP_ADDRESS: redacted.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: redacted
  DISCOURSE_SMTP_PASSWORD: "redacted"

  LETSENCRYPT_ACCOUNT_EMAIL: info@example.com


volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

run:
  - exec: echo "Beginning of custom commands"
  - exec: echo "End of custom commands"

labels:
  app_name:                                                                     discourse

  traefik.enable:                                                               true
  traefik.docker.network:                                                       proxy
  traefik.http.routers.discourse.rule:                                          Host(`forum.example.com`)
  traefik.http.routers.discourse.entrypoints:                                   http
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https
  traefik.http.services.discourse.loadbalancer.server.port:                     80

  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.example.com`)
  traefik.http.routers.discourse_secure.entrypoints:                            https

  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

docker_args:
  - "--network=proxy"
  - "--expose=80"

أعتقد أنني نفذت أمر docker network connect proxy أيضًا لربط هذا بشبكة traefik.

أقدر أي مساعدة لرؤية ما الذي أفتقده هنا، وأود أيضًا أن أسمع ما إذا كانت إجراءات الأمان الخاصة بي في نصابها الصحيح.

لا أعرف ما الذي ينقصك. إليك ما أفعله في Ansible لتشغيل المواقع باستخدام Traefik:

        --docker-args "-l traefik.frontend.rule=Host:{{discourse_hostname}} \
        -l traefik.frontend.entryPoints=https \
        -l traefik.backend={{discourse_shortname}} \
        -l traefik.port=80"

ثم قم بتشغيل الأمر التالي:

       ./launcher start {{ discourse_yml }} {{ docker_args }}

إن إضافة قواعد Traefik في docker_args بدلاً من ملف YAML تمنحنا ميزة إضافية تتمثل في عدم اهتمام Traefik بالحوض (container) الذي يتم تهيئته.

أظن أن هذا هو Traefik الإصدار 1 ربما؟

آه، آسف. نعم، أنا متأكد تقريبًا من أن هذا Traefik 1، لذا لن أستطيع المساعدة في التفاصيل المحددة.

لا يبدو أنك تُعيّن أي قيم في تلك الملصقات (labels) في app.yml؟ أعتقد أنك تحتاج إلى تعيين قاعدة (rule)، وربما وسيط (middleware)؟

إذا كنت لا تريد توقفًا في الخدمة أثناء عملية التهيئة الأولية، فستحتاج إلى تعيينها باستخدام ./launcher start كما في مثالِي.

ربما يكون “الوسيط” (middleware) هو ما كان يُسمى سابقًا “الواجهة الخلفية” (backend)؟ ستحتاج إلى القيام بشيء ما لتحديد أن حاوية Discourse هي الخادم الذي تريده، و… شيء آخر… لربط واجهة أمامية أو عنوان URL معين بالواجهة الخلفية/الخادم المناسب.

يتم تعيينها، لكن عليك التمرير قليلاً إلى اليمين لرؤيتها. مجرد مسألة تنسيق.

شكرًا لك

ههه. عذراً على ذلك.

حسنًا، لا أعرف ما أتحدث عنه، لكن لا يبدو منطقيًا بالنسبة لي أن تقوم بتكوين discourse@docker كموزع أحمال.

مرحباً، أعتقد أنني فهمت الأمر.

حذفت السطر:
# traefik.http.services.discourse_secure.loadbalancer.server.port: 80

ولكنني تركت هذا السطر:

traefik.http.services.discourse.loadbalancer.server.port: 80

labels:
  app_name:                                                                     discourse

  #----Traefik lables------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       proxy
   #---HTTP ROUTER SECTION-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.example.com`)
    #--HTTP SECTION--------------------------
  traefik.http.routers.discourse.entrypoints:                                   http
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https
  traefik.http.services.discourse.loadbalancer.server.port:                     80

   #---HTTPS ROUTER SECTION
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.example.com`)
    #--HTTPS SECTION
  traefik.http.routers.discourse_secure.entrypoints:                            https

 # traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--TLS SECTION
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---MIDDLEWARE SECTION redirect http to https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

لست متأكداً كيف وصلت إلى هذا أو لماذا كان الأمر على هذه الصورة، لكنه يعمل. لذا، باستخدام جميع الإعدادات التي نشرتها أعلاه في الموضوع، مع إجراء هذا التغيير الوحيد، يعمل الأمر الآن بالنسبة لي.

شكراً لكم جميعاً!

هذا صحيح.
لقد أضفت ذلك إلى تكويني:

#—قسم الخدمة يخبر تريفك أين يرسل الطلب
traefik.http.services.discourse.loadbalancer.server.port: 80

هل يثير ذلك شيئًا في ذاكرتك؟
ما تفعله هنا هو تحديد الجهة (الخدمة) التي يُرسل إليها الطلب والمنفذ المستخدم.
يمكنك أيضًا حل هذه المشكلة باستخدام expose، ولكن من منظور أمني، تفضل كشف أقل قدر ممكن من حاوياتك. بالإضافة إلى ذلك، يختار Traefik المنفذ الأول إذا قمت بكشف عدة منافذ، لذا فإن استخدام loadbalancer أنظف.


بيانات Traefik/traefik.yml

أنا لا أفعل ذلك لأن هذا المسار هو المسار الافتراضي.

لا تستخدم المسار الكامل هنا، بل تستخدم المسار الافتراضي. لا أحب ذلك لأنك يجب أن تتذكر المسار. أنا أستخدم storage: /etc/ssl/certs/letsencrypt/acme.json.

أقوم بتعريف الشبكة، ولا أحب الإعدادات الافتراضية.

providers:
  docker:
    exposedByDefault: false
    network: bridge_proxy_traefikv2

حاويات/app.yml

لا تحتاج إلى القيام بذلك، حيث يتم ذلك بواسطة loadbalancer.

تكوين Traefik docker-compose

قد ترغب في إعطاء اسم لهذه الشبكة، وفي حالتي:

networks:
  traefik:
    external:
      name: bridge_proxy_traefikv2

لقد كنت أعمل على توصياتك هنا. شكرًا لك على ردك.

يجب أن أشير إلى أنه بالنسبة لنقطة النهاية، تقول إننا يجب أن نثق بالإعدادات الافتراضية، أما بالنسبة لموقع التخزين فتقول إنك لا تحب الاعتماد على الإعدادات الافتراضية. :slight_smile:

لقد حاولت إجراء التغيير الذي ذكرته بخصوص ملف acme.json:

ومع ذلك، لم يتمكن حاوية Traefik الخاصة بي من العثور على الملف بعد ذلك. ظهر ذلك كخطأ في السجل. لذا تركت الأمر كما هو على acme.json حتى الآن.

أود أن أسأل عن هذا الأمر:

أليس هذا مجرد إعادة تسمية للشبكة أو إعطاؤها اسمًا محليًا؟ أعتقد أنني كنت أشير إليها باسم proxy في الإعدادات الأخرى وفي هذا السياق المحلي. لا تزال لها اسم قمت بتعريفه، أنا فقط لا أعيد تسميتها. على الأقل هذا فهمي.

لدي قلق أخير ملح. لاحظت بعد منشور “نجاح!” أعلاه أنه على الرغم من عمل HTTPS، إلا أنني أحصل على تحذير محتوى مختلط. إذن ليس كل شيء يتم تشفيره.

أحصل على خطأ المحتوى المختلط لتثبيت Discourse الخاص بي، ولكن ليس لتثبيت WordPress الموجود على نفس الخادم. إذن يجب أن يكون الأمر خاصًا بإعدادات Discourse.

عند النظر في وحدة تحكم المطور، أرى:

تحميل محتوى عرض (غير آمن) مختلط “http://talk.redacted.com/uploads/default/optimized/1X/_129430568242d1b7f853bb13ebea28b3f6af4e7_2_180x180.png” على صفحة آمنة FaviconLoader.jsm:174:19

لذا ربما لا يعمل إعادة التوجيه الخاص بي بشكل صحيح بطريقة ما؟

أرفق الملفات ذات الصلة أدناه للمراجعة.

Traefik.yml

api:
dashboard: true

entryPoints:
http:
address: “:80”
https:
address: “:443”

providers:
docker:
exposedByDefault: false
network: proxy

certificatesResolvers:
http:
acme:
email: info@private.com
storage: acme.json
httpChallenge:
entryPoint: http

Traefik docker-compose

version: ‘3’

services:
traefik:
image: traefik:v2.0
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
labels:
- “traefik.enable=true”
- “traefik.http.routers.traefik.entrypoints=http”
- “traefik.http.routers.traefik.rule=Host(monitor.private.com)”
- “traefik.http.middlewares.traefik-auth.basicauth.users=private:private”
- “traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https”
- “traefik.http.routers.traefik.middlewares=traefik-https-redirect”
- “traefik.http.routers.traefik-secure.entrypoints=https”
- “traefik.http.routers.traefik-secure.rule=Host(monitor.private.com)”
- “traefik.http.routers.traefik-secure.middlewares=traefik-auth”
- “traefik.http.routers.traefik-secure.tls=true”
- “traefik.http.routers.traefik-secure.tls.certresolver=http”
- “traefik.http.routers.traefik-secure.service=api@internal”

networks:
proxy:
external: true

app.yml

templates:

  • “templates/postgres.template.yml”
  • “templates/redis.template.yml”
  • “templates/web.template.yml”
  • “templates/web.ratelimited.template.yml”

expose:

params:
db_default_text_search_config: “pg_catalog.english”

db_shared_buffers: “128MB”

env:
LANG: en_US.UTF-8

UNICORN_WORKERS: 2

DISCOURSE_HOSTNAME: talk.private.com

DISCOURSE_DEVELOPER_EMAILS: ‘info@private.com’

LETSENCRYPT_ACCOUNT_EMAIL: info@private.com

volumes:

  • volume:
    host: /var/discourse/shared/standalone
    guest: /shared
  • volume:
    host: /var/discourse/shared/standalone/log/var-log
    guest: /var/log

hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone GitHub - discourse/docker_manager: Plugin for use with discourse docker image · GitHub

run:

  • exec: echo “Beginning of custom commands”
  • exec: echo “End of custom commands”

labels:
app_name: discourse

traefik.enable: true
traefik.docker.network: proxy
traefik.http.routers.discourse.rule: Host(talk.private.com)
traefik.http.routers.discourse.entrypoints: http
traefik.http.routers.discourse.middlewares: discourse_redirect2https
traefik.http.services.discourse.loadbalancer.server.port: 80

traefik.http.routers.discourse_secure.rule: Host(talk.private.com)
traefik.http.routers.discourse_secure.entrypoints: https
traefik.http.routers.discourse_secure.tls: true
traefik.http.routers.discourse_secure.service: discourse
traefik.http.routers.discourse_secure.tls.certresolver: http

traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme: https

docker_args:

  • “–network=proxy”

إذن، أي أفكار حول سبب حصولي على خطأ المحتوى المختلط؟

حسنًا، ظننت للحظة أن نظام Discourse أصبح واعيًا لأنني تلقيت هذا الإشعار في لوحة التحكم الخاصة بي:

ومع ذلك، قمت بهذا التغيير وما زلت أحصل على خطأ المحتوى المختلط. كما قمت بتسجيل الخروج، ومسحت ذاكرة التخزين المؤقت، ثم سجلت الدخول مرة أخرى. النتيجة نفسها.

يبدو أن طلبات تسجيل الدخول الخاصة بي لا تزال مشفرة، وهو أمر جيد على ما أظن، لكنني بحاجة للتخلص من خطأ المحتوى المختلط هذا. الإعدادات مذكورة أعلاه في المنشور السابق.

تحديث آخر: تحذير المحتوى المختلط اختفى الآن. ليس واضحًا بالنسبة لي السبب. أعتقد أنه مرتبط بإعداد force_https، ومع ذلك، لم أحصل على تحميل صفحة نظيف لمدة 30 دقيقة تقريبًا بعد تغيير الإعداد، على الرغم من أنني قمت بمسح ذاكرة التخزين المؤقت وتسجيل الخروج ثم الدخول مرة أخرى، كما أشرت أعلاه.

الخبر السار هو أنني أبدو وكأن لدي تثبيتًا لـ Discourse يعمل خلف وكيل عكسي Traefic.


المشكلة تكمن في الصور التي يتم تحميلها عبر اتصالات HTTP. واجهت نفس المشكلة، راجع:


هل قمت بتحميل الحجم (volume) بشكل صحيح؟ يمكن أن يكون Traefik محيرًا إلى حد ما عندما يتعلق الأمر بالمسارات.
أقوم أنا مثلاً بـ:

volumes:       
  - /etc/ssl/certs/traefik/letsencrypt:/etc/ssl/certs/letsencrypt
  - /opt/traefik/traefik-config.yaml:/etc/traefik/traefik.yaml
  - /etc/passwd.traefik.dashboard:/etc/passwd.BasicAuth.dashboard
  - /etc/passwd.traefik.whoami:/etc/passwd.BasicAuth.whoami

لا أستطيع تذكر السبب بالضبط، لكن كان هناك سببٌ لذلك، ربما لتسهيل رؤيتها في واجهة سطر الأوامر (CLI) عند سرد الشبكات.

لا، لم أقم بالتركيب بهذه الطريقة. إليك قسم الوحدات (volumes) الخاص بي من ملف docker-compose الخاص بـ Traefik:

    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json

ألاحظ أن ملفي لا يذكر حتى “Let’s Encrypt”، بينما ملفك يذكره. أظن أنك قمت بإنشاء المجلد المتداخل بعمق هذا في دليل docker-compose الخاص بك، ووضع ملف acme.json هناك؟

الأشياء الأخرى التي ألاحظها هي أنني أملك docker.sock و localtime. لست متأكدًا مما هو ملف localtime، وربما تكون عبارة docker.sock مشكلة أمنية. أحتاج إلى قراءة المزيد حول ذلك.

يتم إنشاء شهادة Let’s Encrypt بواسطة Traefik. يسمح لي تركيب حجم (volume) بتخزينها على المضيف بدلاً من داخل Docker.
أتذكر أن إتمام جميع عمليات التركيب كان شاقًا حقًا، حيث قمت بجميع الفحوصات باستخدام الأمر docker exec -it:

  • ls
  • dir
  • vi