مناقشة مع Traefik 2.0

Hi all,

I’m migrating to a new server and I want to use Traefik 2.0 as a reverse proxy. I’m currently struggling with the new configuration. I added a section at the bottom of the app.yml file. (Source: Discourse behind Traefik 🐭)

...

expose:
  - "8060:80"   # http
  - "8070:443" # https

...

docker_args:
  - "--network=web"
  - "--expose=8060"
  - "-l traefik.enable=true"
  - "-l traefik.http.routers.forum.rule=Host(`forum.example.com`)"
  - "-l traefik.http.routers.forum.entrypoints=websecure"
  - "-l traefik.http.routers.forum.tls=true"
  - "-l traefik.http.routers.forum.tls.certresolver=mytlschallenge"
  - "-l traefik.http.services.forum.loadbalancer.server.port=8060"
  - "-l traefik.docker.network=web"

This does not seem to work. When I open the route I get a Bad Gateway error. When I go directly to the ip_adress:8060 it opens discourse.

Does anyone have experience with Traefik 2.0?

Thank you!

After some trying I could solve it by my own.

For further notice I attach my app.yml:

...

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  #- "templates/web.socketed.template.yml" 

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
#expose:
#  - "8060:80"   # http
#  - "8070:443" # https

...

docker_args:
  - "--network=web"
  #- "--expose=8060"
  - "-l traefik.enable=true"
  - "-l traefik.http.routers.forum.rule=Host(`forum.example.com`)"
  - "-l traefik.http.routers.forum.entrypoints=websecure"
  - "-l traefik.http.routers.forum.tls=true"
  - "-l traefik.http.routers.forum.tls.certresolver=mytlschallenge"
  - "-l traefik.http.services.forum.loadbalancer.server.port=80"
  - "-l traefik.docker.network=web"

why it is neccessary to sue docker_args? According to https://github.com/discourse/discourse_docker#labels it shall work like:

labels:
  monitor: 'true'
  app_name: {{config}}_discourse

Add labels to the current container. The above will add --l monitor=true -l app_name=dev_discourse to the options when running the container.

Moreover, where is docker_args explained?

@Cameron_D
how did you find out that docker_args is the way to go?

I just couldn’t get the labels section working as expected. I’m not sure exactly why it wasn’t working anymore, or whether or not its been fixed since because I’ve just left my configuration as-is because its working.

مرحباً بك،
هل يمكنك مشاركة إعدادات Traefik الخاصة بك؟

أحصل على رمز 302، يتم إعادة التوجيه تلقائياً إلى HTTPS ثم يتوقف…
لوحة تحكم Traefik تقول إن كل شيء على ما يرام.

إليك ملف docker-compose.yml الخاص بي
version: "3.7"
    services:
      traefik-reverse-proxy:   
        # صورة Docker الرسمية لـ Traefik v2.0
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # أخبر Traefik بالاستماع إلى Docker 
          - --providers.docker          # (الافتراضي: true)
          # تفعيل واجهة API/لوحة التحكم / (تعيين نقطة نهاية Docker للتواصل مع API الخاص بـ Docker)
          - --api=true                    # (الافتراضي: false)
          # تفعيل لوحة التحكم. 
          - --api.dashboard               # (الافتراضي: true)
          # تفعيل واجهة المستخدم الويب / سيقوم Traefik بالاستماع على المنفذ 8080 بشكل افتراضي لطلبات API / تفعيل API مباشرة على نقطة الدخول المسماة traefik. (الافتراضي: false) --> المنفذ '8080'v= نقطة الدخول 'traefik'، يتجاوز --api
          - --api.insecure=true         # (الافتراضي: false) 
          # تفعيل نقاط نهاية إضافية للتصحيح والتحليل. 
          - --api.debug=true            # (الافتراضي: false)
          # تعيين مستوى تصحيح الأخطاء للسجل
          - --log.level=DEBUG    
          # كتابة سجل الوصول
          - --accesslog=true    
          # تحديد موقع التخزين داخل الحاوية، يتم كتابة ملف السجل داخل الحاوية. لجعله متاحاً على المضيف، يتم تركيبه، انظر قسم volumes
          - --log.filePath=/var/traefik-container/logs/traefik-log.log
          - --accesslog.filepath=/var/traefik-container/logs/traefik-access.log
          # تجاوز اسم نقطة الدخول الافتراضي للمنفذ 80 بـ "web"
          - --entrypoints.web.address=:80
          # إعلان اسم نقطة الدخول للمنفذ 443
          - --entrypoints.websecure.address=:443
          #--providers.docker.endpoint=unix:///var/run/docker.sock    
          # Let's Encrypt
          - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true
          - --certificatesresolvers.mytlschallenge.acme.email=my@email.com
          - --certificatesresolvers.mytlschallenge.acme.storage=/var/traefik-container/letsencrypt/acme.json
        ports:
          # منفذ HTTP
          - "80:80"
          # منفذ HTTPS
          - "443:443"
          # واجهة المستخدم الويب (مفعلة بواسطة --api.insecure=true)
          - "8080:8080"
        volumes:        # بناء الجملة --> موقع المضيف:المسار داخل الحاوية
          # حتى يتمكن Traefik من الاستماع إلى أحداث Docker
          - /var/run/docker.sock:/var/run/docker.sock
          - /var/traefik/log:/var/traefik-container/logs
          - /var/traefik/letsencrypt:/var/traefik-container/letsencrypt
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=bridge_proxy_traefikv2"
          - "traefik.http.routers.traefikv2.rule=Host(`traefik.mydomain.community`)"
          - "traefik.http.routers.traefikv2.entrypoints=web"
          - "traefik.http.services.traefikv2.loadBalancer.server.port=80"

        networks:
          - traefik
          #- default
          
       # خادم ويب صغير بلغة Go يطبع معلومات النظام وطلبات HTTP إلى المخرجات
    #  whoami:
    #    image: "containous/whoami"
    #    container_name: "whoami"
    #    labels:
    #      - "traefik.enable=true"
    #      - "traefik.docker.network=bridge_proxy_traefikv2"
    #      - "traefik.http.routers.whoami.rule=Host(`mydomain.community`)"
    #      - "traefik.http.routers.whoami.entrypoints=web"
    #      - "traefik.http.services.whoami.loadBalancer.server.port=80"
    #    networks:
    #      - traefik
    #      #- default
          
      whoami_sub:
        image: "containous/whoami"
        container_name: "whoami_sub"
        labels:
          - "traefik.enable=true"
          - "traefik.name=whoami_sub"
          - "traefik.docker.network=bridge_proxy_traefikv2"
          - "traefik.http.routers.whoami_sub.rule=Host(`whoami.mydomain.community`)"
          - "traefik.http.routers.whoami_sub.entrypoints=web"
          #- "traefik.http.services.whoami_sub.loadBalancer.server.port=80"
        networks:
          - traefik
          - default

    networks:
      traefik:
        external:
          name: bridge_proxy_traefikv2
إليك ملف app.yml الخاص بتطبيق Discourse
## هذا هو قالب حاوية Docker المستقل الشامل لـ Discourse
##
## بعد إجراء تغييرات على هذا الملف، يجب عليك إعادة البناء
## /var/discourse/launcher rebuild app
##
## كن حذراً جداً عند التعديل!
## ملفات YAML حساسة جداً للأخطاء في المسافات البيضاء أو المحاذاة!
## قم بزيارة http://www.yamllint.com/ للتحقق من صحة هذا الملف عند الحاجة

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## قم بإلغاء التعليق عن هذين السطرين إذا كنت ترغب في إضافة Let's Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## أي منافذ TCP/IP يجب أن تعرضها هذه الحاوية؟
## إذا كنت تريد لـ Discourse مشاركة منفذ مع خادم ويب آخر مثل Apache أو nginx،
## انظر https://meta.discourse.org/t/17247 للحصول على التفاصيل
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## تعيين db_shared_buffers إلى حد أقصى 25% من إجمالي الذاكرة.
  ## سيتم تعيينها تلقائياً بواسطة bootstrap بناءً على الذاكرة المكتشفة، أو يمكنك تجاوزها
  db_shared_buffers: "128MB"

  ## يمكن أن يحسن أداء الفرز، لكنه يضيف استخدام الذاكرة لكل اتصال
  #db_work_mem: "40MB"

  ## أي إصدار Git يجب أن تستخدم هذه الحاوية؟ (الافتراضي: tests-passed)
  #version: tests-passed

labels:
  app_name:                                                 discourse  
  traefik.enable:                                           true
  traefik.docker.network:                                   bridge_proxy_traefikv2  
  traefik.http.services.forum.loadbalancer.server.port:     80
  traefik.http.routers.forum.rule:                          Host(`forum.mydomain.community`)
  traefik.http.routers.forum.entrypoints:                   websecure
  traefik.http.routers.forum.tls:                           true
  traefik.http.routers.forum.tls.certresolver:              mytlschallenge
     
docker_args:
  - "--network=bridge_proxy_traefikv2"
 # - "-l traefik.enable=true"
 # - "-l traefik.http.routers.forum.rule=Host(`fairbnb.community`)"
 # - "-l traefik.http.routers.forum.entrypoints=websecure"
 # - "-l traefik.http.routers.forum.tls=true"
 # - "-l traefik.http.routers.forum.tls.certresolver=mytlschallenge"
 # - "-l traefik.http.services.forum.loadbalancer.server.port=80"
 # - "-l traefik.docker.network=web"
  
env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## كم عدد طلبات الويب المتزامنة المدعومة؟ يعتمد على الذاكرة ونوى المعالج.
  ## سيتم تعيينها تلقائياً بواسطة bootstrap بناءً على المعالجات المكتشفة، أو يمكنك تجاوزها
  UNICORN_WORKERS: 2

  ## TODO: اسم النطاق الذي ستستجيب له هذه النسخة من Discourse
  ## مطلوب. لن يعمل Discourse مع عنوان IP مجرد.
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## قم بإلغاء التعليق إذا كنت تريد تشغيل الحاوية بنفس اسم المضيف (-h option) المحدد أعلاه (الافتراضي "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: قائمة عناوين البريد الإلكتروني المفصولة بفواصل والتي سيتم تعيينها كمسؤول ومطور
  ## عند التسجيل الأولي، مثال 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'discourse@myemail.com'

  ## TODO: خادم البريد SMTP المستخدم للتحقق من الحسابات الجديدة وإرسال الإشعارات
  ## مطلوب عنوان SMTP واسم المستخدم وكلمة المرور
  ## تحذير: قد يسبب حرف '#' في كلمة مرور SMTP مشاكل!
  DISCOURSE_SMTP_ADDRESS: smtp.zoho.eu
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: discourse@myemail.com
  DISCOURSE_SMTP_PASSWORD: "tempPassword"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (اختياري، الافتراضي true)

  ## إذا أضفت قالب Let's Encrypt، قم بإلغاء التعليق أدناه للحصول على شهادة SSL مجانية
  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## عنوان CDN http أو https لهذه النسخة من Discourse (مُعد للاستخراج)
  ## انظر https://meta.discourse.org/t/14857 للحصول على التفاصيل
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
## حاوية Docker عديمة الحالة؛ يتم تخزين جميع البيانات في /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## تذهب الإضافات هنا
## انظر https://meta.discourse.org/t/19157 للحصول على التفاصيل
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: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "End of custom commands"

There were problems make Traefik’s dashboard available via a subdomain but discourse is still not reachable, see https://community.containo.us/t/discourse-instance-is-handled-by-api-internal-is-that-normal/3690/1
Here are my working configs.

  1. With my comments

    docker-compose: traefikV2_docker-compose.yaml
    # https://stackoverflow.com/questions/49718431/docker-compose-yml-file-naming-convention
    version: "3.7"
    
    services:
      traefik-reverse-proxy:   
        # The official v2.0 Traefik docker image
        #image: traefik:latest 
        #image: traefik:v2.0
        image: traefik:v2.1.1
        container_name: traefik
        #command: 
        ## to work with custom traefik configuration file you have to declare the local path and mount the location on the host, see volume section
        #- --configFile=/etc/traefik/traefik-config.yaml
        
        ports:
          # The HTTP port
          - 80:80
          # The HTTPS port
          - 443:443
          # The Web UI (enabled by --api.insecure=true)
          #- "8080:8080"
        
        volumes:         
        # syntax --> host-location:path-in-container, see https://docs.docker.com/compose/compose-file/#volumes
          # So that Traefik can listen to the Docker events
          - /var/run/docker.sock:/var/run/docker.sock
          # mount the location for the log files to the host, so that I can read them on the host
            # chosen based on https://unix.stackexchange.com/questions/104936/where-are-all-the-posibilities-of-storing-a-log-file
          - /var/log/traefik:/var/log
          # mount the location for the certifcates to the host, so that I can read them on the host
            #based on https://www.getpagespeed.com/server-setup/ssl-directory and https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux
          - /etc/ssl/certs/traefik/letsencrypt:/etc/ssl/certs/letsencrypt
          # I use a customized "traefik.toml", so it has to be mounted into the traefik container (or stored there), combine 
            # https://stackoverflow.com/questions/47382756/why-is-my-traefik-toml-file-not-be-read-by-docker-compose-configuration
            # https://stackoverflow.com/questions/57200728/can-the-default-location-of-the-traefik-configuration-file-be-changed-in-the-off
            # https://stackoverflow.com/questions/45902133/how-to-use-custom-traefik-toml-file
            # https://docs.traefik.io/getting-started/configuration-overview/
          - /opt/traefik/traefik-config.yaml:/etc/traefik/traefik.yaml
        
        labels:
          - traefik.enable=true
          #- "traefik.docker.network=bridge_proxy_traefikv2"
          - traefik.http.routers.traefik_dashboard-router.rule=Host(`traefik.fairbnb.community`)
          - traefik.http.routers.traefik_dashboard-router.entrypoints=web
          #- "traefik.http.services.traefik_dashboard-service.loadBalancer.server.port=8080"
          - traefik.http.routers.traefik_dashboard-router.service=api@internal
    
        networks:
          - traefik
          #- default
          
       #Tiny Go webserver that prints os information and HTTP request to output
       #  whoami:
       #    image: "containous/whoami"
       #    container_name: "whoami"
       #    labels:
       #      - "traefik.enable=true"
       #      - "traefik.docker.network=bridge_proxy_traefikv2"
       #      - "traefik.http.routers.whoami-router.rule=Host(`fairbnb.community`)"
       #      - "traefik.http.routers.whoami-router.entrypoints=web"
       #      - "traefik.http.services.whoami-service.loadBalancer.server.port=80"
       #    networks:
       #      - traefik
       #      #- default
          
      whoami_viaSubdomain:
        image: "containous/whoami"
        container_name: "whoami_viaSubdomain"
        labels:
          - traefik.enable=true
          - traefik.docker.network=bridge_proxy_traefikv2
          - traefik.http.routers.whoami_viaSubdomain-router.rule=Host(`whoami.fairbnb.community`)
          - traefik.http.routers.whoami_viaSubdomain-router.entrypoints=web
          #- "traefik.http.services.whoami_viaSubdomain-service.loadBalancer.server.port=80"
        networks:
          - traefik
          #- default
    
    networks:
      traefik:
        external:
          name: bridge_proxy_traefikv2
           
           
    
    
    
    Traefik configuration: traefik-config.yaml
    global:
      checkNewVersion: true
    #  sendAnonymousUsage: true
    #serversTransport:
    #  insecureSkipVerify: true
    #  rootCAs:
    #  - foobar
    #  maxIdleConnsPerHost: 42
    #  forwardingTimeouts:
    #    dialTimeout: 42
    #    responseHeaderTimeout: 42
    #    idleConnTimeout: 42
    
    entryPoints:
      web:
        address: :80
        #transport:
        #  lifeCycle:
        #    requestAcceptGraceTimeout: 42
        #    graceTimeOut: 42
        #  respondingTimeouts:
        #    readTimeout: 42
        #    writeTimeout: 42
        #    idleTimeout: 42
        #proxyProtocol:
        #  insecure: true
        #  trustedIPs:
        #  - foobar
        #  - foobar
        #forwardedHeaders:
        #  insecure: true
        #  trustedIPs:
        #  - foobar
        #  - foobar
      websecure:
        address: :443
      #traefik_dashboard:
         #address: ":8080"     
    
    api: 
    #api: {}   
    # Activate dashboard. 
      ## Enables the web UI @ port 8080/ Traefik will listen on port 8080 by default for API request. / Activate API directly on the entryPoint named traefik. (Default: false) --> port '8080'v= entryPoint 'traefik', overrides --api  
      #insecure: true
      ## Activate dashboard. (Default: true)
      # dashboard: true
      # Enable additional endpoints for debugging and profiling. 
       debug: true    
      
    providers:
    # providersThrottleDuration: 42
      docker:
        #constraints: foobar
        ## Watch provider. (Default: true)
        #watch: true
        ## Docker server endpoint. Can be a tcp or a unix socket endpoint. (Default: unix:///var/run/docker.sock)
        #endpoint: unix:///var/run/docker.sock
        #defaultRule: foobar
        #tls:
          #ca: foobar
          #caOptional: true
          #cert: foobar
          #key: foobar
          #insecureSkipVerify: true
        # Expose containers by default. (Default: true) / By default, routes for all detected containers are creates. ITo limit the scope of Traefik's service discovery, i.e. disallow route creation for some containers, you can do so in two different ways: gerneric exposedByDefault (overriden by traefik.enable), or with a finer granularity mechanism based on constraints.
        exposedByDefault: false
        #useBindPortIP: true
        #swarmMode: true
        # Default Docker network used.
        network: bridge_proxy_traefikv2
        # swarmModeRefreshSeconds: 42  
    
    not used currently-metrics:    # this is only hear to fold/unfold the commented region in  Notepad++
    #metrics:
    #  prometheus:
    #    buckets:
    #    - 42
    #    - 42
    #    addEntryPointsLabels: true
    #    addServicesLabels: true
    #    entryPoint: foobar
    #    manualRouting: true
    #  datadog:
    #    address: foobar
    #    pushInterval: 42
    #    addEntryPointsLabels: true
    #    addServicesLabels: true
    #  statsD:
    #    address: foobar
    #    pushInterval: 42
    #    addEntryPointsLabels: true
    #    addServicesLabels: true
    #    prefix: traefik
    #  influxDB:
    #    address: foobar
    #    protocol: foobar
    #    pushInterval: 42
    #    database: foobar
    #    retentionPolicy: foobar
    #    username: foobar
    #    password: foobar
    #    addEntryPointsLabels: true
    #    addServicesLabels: true
    #ping:
    #  entryPoint: foobar
    #  manualRouting: true
       #
    log:
    #Traefik's log file 
      # set debug level of the log
      level: DEBUG
      # defining the storage location inside the container, log file is written inside the container. To make it avaiable on the host it is mounted, see volumes section in docker-compose file
        # chosen based on https://unix.stackexchange.com/questions/104936/where-are-all-the-posibilities-of-storing-a-log-file
      filePath: /var/log/traefik-log.log
      # Traefik log format: json | common (Default: common)
      #format: common
    
    accessLog:      
    # Logging access attempts   
      # defining the storage location inside the container, log file is written inside the container. To make it avaiable on the host it is mounted, see volumes section in docker-compose file
        # chosen based on https://unix.stackexchange.com/questions/104936/where-are-all-the-posibilities-of-storing-a-log-file  
      filePath: /var/log/traefik-access.log
      # Access log format: json | common (Default: common)
      #format: common
    #  filters:
    #    statusCodes:
    #    - foobar
    #    - foobar
    #    retryAttempts: true
    #    minDuration: 42
    #  fields:
    #    defaultMode: foobar
    #    names:
    #      name0: foobar
    #      name1: foobar
    #    headers:
    #      defaultMode: foobar
    #      names:
    #        name0: foobar
    #        name1: foobar
    #  bufferingSize: 42
       #
       
    not used currently-tracing:    # this is only hear to fold/unfold the commented region in  Notepad++
    #tracing:   
    #  serviceName: foobar
    #  spanNameLimit: 42
    #  jaeger:
    #    samplingServerURL: foobar
    #    samplingType: foobar
    #    samplingParam: 42
    #    localAgentHostPort: foobar
    #    gen128Bit: true
    #    propagation: foobar
    #    traceContextHeaderName: foobar
    #    collector:
    #      endpoint: foobar
    #      user: foobar
    #      password: foobar
    #  zipkin:
    #    httpEndpoint: foobar
    #    sameSpan: true
    #    id128Bit: true
    #    sampleRate: 42
    #  datadog:
    #    localAgentHostPort: foobar
    #    globalTag: foobar
    #    debug: true
    #    prioritySampling: true
    #    traceIDHeaderName: foobar
    #    parentIDHeaderName: foobar
    #    samplingPriorityHeaderName: foobar
    #    bagagePrefixHeaderName: foobar
    #  instana:
    #    localAgentHost: foobar
    #    localAgentPort: 42
    #    logLevel: foobar
    #  haystack:
    #    localAgentHost: foobar
    #    localAgentPort: 42
    #    globalTag: foobar
    #    traceIDHeaderName: foobar
    #    parentIDHeaderName: foobar
    #    spanIDHeaderName: foobar
    #    baggagePrefixHeaderName: foobar
       #
    not used currently-hostResolver:     # this is only hear to fold/unfold the commented region in  Notepad++
    #hostResolver:
    #  cnameFlattening: true
    #  resolvConfig: foobar
    #  resolvDepth: 42
      #
    certificatesResolvers:
      tlsChallenge_letsencrypt:
        acme:
          email: my.secret@gmail.com
          # CA server to use. (Default: https://acme-v02.api.letsencrypt.org/directory)
          #caServer:        
          # location chosen based on  on https://www.getpagespeed.com/server-setup/ssl-directory and https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux
          storage: /etc/ssl/certs/letsencrypt/acme.json
          # KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. (Default: RSA4096)
          #keyType: {}         
          #dnsChallenge:
            # provider: foobar
            # delayBeforeCheck: 42
            # resolvers:
            # - foobar
            # - foobar
            # disablePropagationCheck: true
          #httpChallenge:
            # entryPoint: foobar
          tlsChallenge: {}
      #CertificateResolver1:
      #  acme:
      #    email: my.secret@gmail.com
      #    caServer: foobar
      #    storage: foobar
      #    keyType: foobar
      #    dnsChallenge:
      #      provider: foobar
      #      delayBeforeCheck: 42
      #      resolvers:
      #      - foobar
      #      - foobar
      #      disablePropagationCheck: true
      #    httpChallenge:
      #      entryPoint: foobar
      #    tlsChallenge: {}
    
  2. Without my comments

    docker-compose: traefikV2_docker-compose.yaml
    root@Ubuntu18:/opt/10_docker-compose.yml-files# cat traefikV2_docker-compose.yaml | grep -v "#"
    version: "3.7"
    
    services:
      traefik-reverse-proxy:
        image: traefik:v2.1.1
        container_name: traefik
    
        ports:
          - 80:80
          - 443:443
    
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - /var/log/traefik:/var/log
          - /etc/ssl/certs/traefik/letsencrypt:/etc/ssl/certs/letsencrypt
          - /opt/traefik/traefik-config.yaml:/etc/traefik/traefik.yaml
    
        labels:
          - traefik.enable=true
          - traefik.http.routers.traefik_dashboard-router.rule=Host(`traefik.fairbnb.community`)
          - traefik.http.routers.traefik_dashboard-router.entrypoints=web
          - traefik.http.routers.traefik_dashboard-router.service=api@internal
    
        networks:
          - traefik
    
    
      whoami_viaSubdomain:
        image: "containous/whoami"
        container_name: "whoami_viaSubdomain"
        labels:
          - traefik.enable=true
          - traefik.docker.network=bridge_proxy_traefikv2
          - traefik.http.routers.whoami_viaSubdomain-router.rule=Host(`whoami.fairbnb.community`)
          - traefik.http.routers.whoami_viaSubdomain-router.entrypoints=web
        networks:
          - traefik
    
    networks:
      traefik:
        external:
          name: bridge_proxy_traefikv2
    
    
    Traefik configuration: traefik-config.yaml
    root@Ubuntu18:/opt/traefik# cat traefik-config.yaml | grep -v "#"
    global:
      checkNewVersion: true
    
    entryPoints:
      web:
        address: :80
      websecure:
        address: :443
    
    api:
       debug: true
    
    providers:
      docker:
        exposedByDefault: false
        network: bridge_proxy_traefikv2
    
    log:
      level: DEBUG
      filePath: /var/log/traefik-log.log
    
    accessLog:
      filePath: /var/log/traefik-access.log
    
    certificatesResolvers:
      tlsChallenge_letsencrypt:
        acme:
          email: my.secret@gmail.com
          storage: /etc/ssl/certs/letsencrypt/acme.json
          tlsChallenge: {}
    
    

@Cameron_D
@SvenC56
@Cerix
@huberfe
عذراً على الإشارة المباشرة إليكم، لكن يبدو أنكم المستخدمون الوحيدون الموثقون الذين يشغّلون Discourse خلف Traefik.
رغم الوعود بأن Traefik ستهتم بكل شيء، يبدو أن الإعداد ليس بهذه البساطة.
حتى الآن، لم أتمكن من النجاح:

عناوين URL العاملة:
عنوان URL غير عامل:

سأكون ممتناً للغاية إذا شاركتم تكوين Discourse و Traefik الكامل، مما يتيح لي استكشاف المشكلة بشكل أفضل.

تكوينات Traefik الخاصة بي في نهاية هذا المنشور: Endless 502 / forwarding when calling dashboard via subdomain #6123 - #9 by PackElend - Traefik v2 - Traefik Labs Community Forum

بما أنني أستخدم الهاتف المحمول فقط، يرجى التحقق من إعداداتي هنا: traefik - SeAT Discourse Documentation
ملاحظة: لقد نجح تشغيله مع الإصدارين 1.6 و 1.7 من Traefik فقط. لا أعرف ما إذا كان سيعمل مع الإصدار 2.

مع ذلك، تمكن مستخدمون متعددون من استخدام ملحقي، واستخدام Discourse و Traefik.

ملاحظة: لم أقرأ منشورًا واحدًا في هذا الموضوع، وأجيب فقط بناءً على التنبيه.

شكرًا جزيلاً :slight_smile: :partying_face:

سأحاول ترحيله من الإصدار 1 إلى الإصدار 2.

لقد بدأت بالفعل في تكوين فكرة حول الأمر، وأحتاج إلى بضع ساعات للتفكير فيه بعمق.

أفترض أن قوالب SSL و Let’s Encrypt معقّدة، بحيث يبدو قسم القوالب كما يلي:

    templates:
          - "templates/postgres.template.yml"
          - "templates/redis.template.yml"
          - "templates/web.template.yml"
          - "templates/web.ratelimited.template.yml"
        ## قم بإلغاء التعليق عن السطرين التاليين إذا كنت ترغب في إضافة Let's Encrypt (https)
          #- "templates/web.ssl.template.yml"
          #- "templates/web.letsencrypt.ssl.template.yml"

نعم، لماذا تريد أن يدير حاوية Discourse شهادات SSL الخاصة بك إذا كنت تنوي تمكين وكيل أمامي؟

يرجى نشر حلك بمجرد الانتهاء.

في Run other websites on the same machine as Discourse - #301 انظر

أقترح إضافة قسم القوالب في الوثائق أيضًا. لاحظت أنه لم يتم التعليق عليه في تثبيتاتي، حيث قمت أولاً بالتثبيت المستقل للحصول على app.yml. في البداية، نسيت التعليق عليها. يمكن أن يتجنب ذلك أن يواجه الآخرون نفس المشكلة.

بالتأكيد

لا يظهر هذا الإعداد الثابت لـ Traefik، أليس كذلك؟

أخبار جيدة للجميع ! http://forum.fairbnb.community/ متاح.

هذا هو التكوين بأقل تغييرات في app.yml ليعمل عبر http، وسأنتقل إلى https في عطلة نهاية الأسبوع.

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## قم بإلغاء التعليق عن هذين السطرين إذا كنت ترغب في إضافة Lets Encrypt (https)
    #- "templates/web.ssl.template.yml"
    #- "templates/web.letsencrypt.ssl.template.yml"  

expose:
      #- "80:80"   # http
      #- "443:443" # https

labels:
    traefik.enable:                                               true
    traefik.http.services.discourse.loadbalancer.server.port:     80
    traefik.http.routers.discourse.rule:                          Host(`forum.fairbnb.community`)
    traefik.http.routers.discourse.entrypoints:                   web

بالنسبة لـ SSL، قم ببساطة بتكوين Traefik مع Let’s Encrypt، ولا تحتاج إلى استخدام discourse ssl.

سيقوم Traefik بإدارة التشفير لجميع الحاويات الخاصة بك.

حاليًا، أستخدم Traefik الإصدار 1.6، لذا لا أعرف بعد كيفية تمكينه في Traefik الإصدار 2.

نعم، انظر إلى https://meta.discourse.org/t/running-other-websites-on-the-same-machine-as-discourse/17247، ولكن يبدو أن Discourse يتوقع معلومات معينة في الرؤوس (headers) عندما يتحدث العميل مع الوكيل عبر HTTPS.

لقد قرأت عنه بشكل سريع. سأحاول شرحه بلغة يفهمها المستخدم العادي.

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

إذًا، هل تستخدم HTTPS للوصول إلى المنتدى الخاص بك؟
هل يمكنك مشاركة إعدادات Traefik وDiscourse؟ كلما زادت المعلومات المشتركة، كان من الأسهل عليّ التعامل مع الأمر خلال عطلة نهاية الأسبوع.
يوجد دليل للانتقال من الإصدار V1 إلى V2 في https://docs.traefik.io/migration/v1-to-v2/، لكنني سأحاول شرحه هنا خلال عطلة نهاية الأسبوع.

حسناً، هذا هو ملف traefik.toml الخاص بي، وهو غير صالح للإصدار الجديد v2

defaultEntryPoints = ["http", "https"]

[web]
address = ":8080"
  [web.auth.basic]
  users = ["yourusername:yourpassword"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

[acme]
email = "XXXXXXXX"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
onDemand = false
[acme.httpChallenge]
entryPoint = "http"
minVersion = "VersionTLS12"

جزء من إعدادات Discourse

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"

expose:
  - "80"   # http ------ مجرد تعريض منافذ الحاوية 
  - "443" # https ------ لا تحتاج إلى تعريض منفذ المضيف الخارجي

labels:
  traefik.port: '80'
  traefik.backend: 'mycontainername'
  traefik.frontend.rule: 'Host:www.myhost.com'
  traefik.docker.network: 'mynetworkname'
docker_args:
  - "--network=mynetworkname"

مع هذا الإعداد، يعيد Traefik توجيه جميع الطلبات من المنفذ 80 “http” إلى المنفذ 443 “https”،
قم بتفعيل خيار FORCE HTTPS في لوحة إدارة Discourse لتجنب الأخطاء.

@pfaffman، لا أعرف ما إذا كانت الإشعارات تعمل بعد، لذا قمت بوسمك في حال قمت بذكر ردك في موضوع آخر.

إذن، يبدو أن إعداداتك تشبه ما ورد أعلاه، ولكن:

مع استخدام متغيرات البيئة (يُشار إلى هذا النهج في https://stackoverflow.com/questions/52804610/how-do-you-set-environmental-variables-for-traefik و https://blog.raveland.org/post/traefik_compose)

لذا يعمل HTTPS :partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
وأعتقد أنني فهمت كيف يعمل كل ذلك :slight_smile:. سأحاول تدوين ذلك في الأيام القادمة

إعداداتي

استخراج ملف discourse app.yml

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## قم بإلغاء التعليق عن هذين السطرين إذا كنت ترغب في إضافة Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## ما هي منافذ TCP/IP التي يجب أن يعرضها هذا الحاوية؟
## إذا كنت ترغب في مشاركة Discourse لمنفذ مع خادم ويب آخر مثل Apache أو nginx،
## راجع https://meta.discourse.org/t/17247 للتفاصيل
expose:
  #- "80:80"   # http
  #- "443:443" # https
  #- "80"      # http
  #- "443"     # https
  #- "40080:80"
  #- "40443:443"

labels:
  app_name:                                                                     discourse

  #----تسميات Traefik------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       bridge_proxy_traefikv2

   #---قسم التوجيه HTTP-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.fairbnb.community`)
    #--قسم HTTP--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  #traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---قسم التوجيه HTTPS
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.fairbnb.community`)
    #--قسم HTTPS
  traefik.http.routers.discourse_secure.entrypoints:                            websecure
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--قسم TLS
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---قسم الوسائط إعادة توجيه HTTP إلى HTTPS
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

docker_args:
  - "--network=bridge_proxy_traefikv2"
  
params:

إعدادات Traefik الثابتة

global:
  checkNewVersion: true
entryPoints:
  web:
    address: :80
  websecure:
    address: :443

api:
   debug: true

providers:
  docker:
    exposedByDefault: false
    network: bridge_proxy_traefikv2

log:
  level: DEBUG
  filePath: /var/log/traefik-log.log

accessLog:
  filePath: /var/log/traefik-access.log

certificatesResolvers:
  tlsChallenge_letsencrypt:
    acme:
      email: my.secret@gmail.com
      storage: /etc/ssl/certs/letsencrypt/acme.json
      tlsChallenge: {}

مرحبًا،

استخدمت هذا المنشور كدليل لإعداد Discourse للعمل مع Traefik. لدي Traefik يعمل بالفعل مع تطبيق ويب آخر.

عند زيارة forum.private.com، أحصل على رسالة خطأ “404 الصفحة غير موجودة”.

يبدو أن شيئًا ما يعمل، لأنه في لوحة تحكم Traefik ضمن علامة التبويب Services، يمكنني رؤية discourse@docker و discourse_secure@docker.

ومع ذلك، لا يوجد أي شيء يتعلق بـ Discourse في علامة التبويب Routers.

التغييرات التي قمت بها في ملف app.yml موضحة هنا، وهي مستندة بشكل كبير إلى المنشور المذكور أعلاه. أضفت منفذًا ظاهرًا (exposed port) في وسيطات Docker في الأسفل، والذي بدا أنه فتح الخدمات المذكورة أعلاه. سأقدّر أي مساعدة!

Traefik docker-compose
version: "3.3"

services:
  ################################################
  ####        Traefik Proxy Setup           #####
  ###############################################
  traefik:
    image: traefik:v2.0
    restart: always
    container_name: traefik
    ports:
      - "80:80" # <== http
      - "8080:8080" # <== :8080 هو المنفذ الذي تعمل عليه لوحة التحكم
      - "443:443" # <== https
    command:
    #### هذه هي أوامر CLI التي ستقوم بإعداد Traefik وإخباره بكيفية العمل! ####

      - --api.insecure=true # <== تمكين واجهة API غير آمنة، غير موصى به للإنتاج
      - --api.dashboard=true # <== تمكين لوحة التحكم لعرض الخدمات، والوسائط، والمسارات، إلخ...
      - --api.debug=true # <== تمكين نقاط نهاية إضافية لتصحيح الأخطاء والقياس
      ## إعدادات السجلات (الخيارات: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
      - --log.level=DEBUG # <== تحديد مستوى السجلات من Traefik
      ## إعدادات المزود - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== تمكين Docker كمزود لـ Traefik
      - --providers.docker.exposedbydefault=false # <== عدم تعريض كل حاوية لـ Traefik، فقط تعريض المفعّل منها
      - --providers.file.filename=/dynamic.yaml # <== الإشارة إلى ملف إعدادات ديناميكي
      - --providers.docker.network=web # <== التشغيل على شبكة Docker المسماة web
      ## إعدادات نقاط الدخول - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== تعريف نقطة دخول للمنفذ :80 باسم web
      - --entrypoints.web-secured.address=:443 # <== تعريف نقطة دخول لـ HTTPS على المنفذ :443 باسم web-secured
      ## إعدادات الشهادات (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== تمكين TLS-ALPN-01 لتوليد وتجديد شهادات ACME
      - --certificatesresolvers.mytlschallenge.acme.email=private@private.com # <== تعيين البريد الإلكتروني للشهادات
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== تعريف ملف ACME لتخزين معلومات الشهادة
    volumes:
      - ./letsencrypt:/letsencrypt # <== مجلد للشهادات (TLS)
      - /var/run/docker.sock:/var/run/docker.sock # <== مجلد لإدارة Docker
      - ./dynamic.yaml:/dynamic.yaml # <== مجلد لملف الإعدادات الديناميكي، **مرجع: السطر 27
    networks:
      - web # <== وضع Traefik على الشبكة المسماة web للوصول إلى الحاويات على هذه الشبكة
    labels:
    #### تحدد العلامات سلوك وقواعد وكيل Traefik لهذه الحاوية ####
      - "traefik.enable=true" # <== تمكين Traefik على نفسه لعرض لوحة التحكم وتعيين نطاق فرعي لعرضه
      - "traefik.http.routers.api.rule=Host(`monitor.private.com`)" # <== تعيين النطاق الخاص بلوحة التحكم
      - "traefik.http.routers.api.service=api@internal" # <== تمكين الواجهة كخدمة للوصول إليها


networks:
  web:
    external: true
  backend:
    external: false

volumes:
  db_data: {}
  wordpress:
    external: true
  db:
    external: true

Discourse app.yml
## هذا هو قالب حاوية Docker المستقل لـ Discourse (all-in-one)
##
## بعد إجراء تغييرات على هذا الملف، يجب عليك إعادة البناء
## /var/discourse/launcher rebuild app
##
## كن *حذرًا جدًا* عند التعديل!
## ملفات YAML حساسة للغاية للأخطاء في المسافات البيضاء أو المحاذاة!
## قم بزيارة http://www.yamllint.com/ للتحقق من صحة هذا الملف حسب الحاجة

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## قم بإلغاء التعليق عن هذين السطرين إذا كنت ترغب في إضافة Let's Encrypt (https)
  #- "templates/web.ssl.template.yml"
  # "templates/web.letsencrypt.ssl.template.yml"

## أي منافذ TCP/IP يجب أن تعرضها هذه الحاوية؟
## إذا كنت ترغب في مشاركة منفذ مع خادم ويب آخر مثل Apache أو nginx،
## راجع https://meta.discourse.org/t/17247 للحصول على التفاصيل
expose:
  #- "80:80"   # http
  #- "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## قم بتعيين db_shared_buffers إلى أقصى 25% من إجمالي الذاكرة.
  ## سيتم تعيينها تلقائيًا بواسطة bootstrap بناءً على الذاكرة المكتشفة، أو يمكنك تجاوزها
  db_shared_buffers: "128MB"

  ## يمكن أن يحسن أداء الفرز، لكنه يزيد من استخدام الذاكرة لكل اتصال
  #db_work_mem: "40MB"

  ## أي إصدار Git يجب أن تستخدمه هذه الحاوية؟ (الافتراضي: tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## كم عدد طلبات الويب المتزامنة المدعومة؟ يعتمد على الذاكرة ونوى المعالج.
  ## سيتم تعيينها تلقائيًا بواسطة bootstrap بناءً على المعالجات المكتشفة، أو يمكنك تجاوزها
  UNICORN_WORKERS: 2

  ## TODO: اسم النطاق الذي ستستجيب له هذه النسخة من Discourse
  ## مطلوب. لن يعمل Discourse مع عنوان IP عاري.
  DISCOURSE_HOSTNAME: forum.private.com

  ## قم بإلغاء التعليق إذا كنت تريد تشغيل الحاوية بنفس اسم النطاق (-h option) المحدد أعلاه (الافتراضي "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: قائمة عناوين البريد الإلكتروني المفصولة بفواصل سيتم تعيينها كمسؤولين ومطورين
  ## عند التسجيل الأولي مثال 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'private@private.com'

  ## TODO: خادم البريد SMTP المستخدم للتحقق من الحسابات الجديدة وإرسال الإشعارات
  ## مطلوب عنوان SMTP واسم مستخدم وكلمة مرور
  # WARNING قد يتسبب حرف '#' في كلمة مرور SMTP في حدوث مشاكل!
  DISCOURSE_SMTP_ADDRESS: in-v3.mailjet.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: redacted
  DISCOURSE_SMTP_PASSWORD: "redacted"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (اختياري، الافتراضي true)

  ## إذا أضفت قالب Let's Encrypt، قم بإلغاء التعليق أدناه للحصول على شهادة SSL مجانية
  LETSENCRYPT_ACCOUNT_EMAIL: private@private.com

  ## عنوان CDN http أو https لهذه النسخة من Discourse (مُهيأ للسحب)
  ## راجع https://meta.discourse.org/t/14857 للحصول على التفاصيل
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## حاوية Docker عديمة الحالة؛ يتم تخزين جميع البيانات في /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## تذهب الإضافات هنا
## راجع https://meta.discourse.org/t/19157 للحصول على التفاصيل
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## أي أوامر مخصصة للتشغيل بعد البناء
run:
  - exec: echo "Beginning of custom commands"
  ## إذا كنت ترغب في تعيين عنوان البريد الإلكتروني 'From' لأول تسجيل، قم بإلغاء التعليق وتغييره:
  ## بعد الحصول على أول بريد إلكتروني للتسجيل، أعد التعليق على السطر. يجب تشغيله مرة واحدة فقط.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

labels:
  app_name:                                                                     discourse

  #----علامات Traefik------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       web

   #---قسم المسار HTTP-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.private.com`)
    #--قسم HTTP--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---قسم المسار HTTPS
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.private.com`)
    #--قسم HTTPS
  traefik.http.routers.discourse_secure.entrypoints:                            web-secured
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--قسم TLS
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---قسم الوسائط redirect http to https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

شكرًا لك