Diskussion mit Traefik 2.0

Hallo zusammen,

ich migriere auf einen neuen Server und möchte Traefik 2.0 als Reverse-Proxy verwenden. Ich habe derzeit Schwierigkeiten mit der neuen Konfiguration. Ich habe am Ende der app.yml-Datei einen Abschnitt hinzugefügt. (Quelle: 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"

Das scheint nicht zu funktionieren. Wenn ich die Route öffne, erhalte ich einen Bad Gateway-Fehler. Wenn ich direkt auf die IP-Adresse:8060 zugreife, öffnet sich Discourse.

Hat jemand Erfahrung mit Traefik 2.0?

Vielen Dank!

Nach einigem Probieren konnte ich es selbst lösen.

Für weitere Hinweise füge ich meine app.yml an:

...

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Diese beiden Zeilen kommentieren Sie aus, wenn Sie Lets Encrypt (https) hinzufügen möchten
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  #- "templates/web.socketed.template.yml" 

## Welche TCP/IP-Ports soll dieser Container freigeben?
## Wenn Sie Discourse einen Port mit einem anderen Webserver wie Apache oder nginx teilen möchten,
## siehe https://meta.discourse.org/t/17247 für 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"

Warum ist es notwendig, docker_args zu verwenden? Laut GitHub - discourse/discourse_docker: A Docker image for Discourse · GitHub sollte es so funktionieren:

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

Labels zum aktuellen Container hinzufügen. Das obige Beispiel fügt --l monitor=true -l app_name=dev_discourse zu den Optionen beim Starten des Containers hinzu.

Außerdem: Wo wird docker_args erklärt?

@Cameron_D
wie bist du darauf gekommen, dass docker_args der richtige Weg ist?

Ich konnte den Abschnitt „Labels

Hallo,
könntest du deine Traefik-Konfiguration teilen?

Ich erhalte eine 302-Antwort, die automatisch zu HTTPS weiterleitet, und dann hört es auf…
Das Traefik-Dashboard zeigt alles als in Ordnung an.

Meine docker-compose.yml befindet sich hier
version: "3.7"
    services:
      traefik-reverse-proxy:   
        # Das offizielle v2.0 Traefik Docker-Image
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # Traefik anweisen, auf Docker zu hören
          - --providers.docker          # (Standard: true)
          # API/Dashboard aktivieren / (das Docker-Endpoint für die Kommunikation mit der Docker-API festlegen)
          - --api=true                    # (Standard: false)
          # Dashboard aktivieren.
          - --api.dashboard               # (Standard: true)
          # Web-UI aktivieren / Traefik lauscht standardmäßig am Port 8080 auf API-Anfragen. / API direkt am EntryPoint namens "traefik" aktivieren. (Standard: false) --> Port '8080'v= EntryPoint 'traefik', überschreibt --api
          - --api.insecure=true         # (Standard: false) 
          # Zusätzliche Endpunkte für Debugging und Profiling aktivieren.
          - --api.debug=true            # (Standard: false)
          # Debug-Level des Logs festlegen
          - --log.level=DEBUG    
          # Zugriffslog schreiben
          - --accesslog=true    
          # Speicherort innerhalb des Containers definieren, die Logdatei wird im Container geschrieben. Um sie auf dem Host verfügbar zu machen, wird sie gemountet, siehe Abschnitt volumes
          - --log.filePath=/var/traefik-container/logs/traefik-log.log
          - --accesslog.filepath=/var/traefik-container/logs/traefik-access.log
          # Den Standard-EntryPoint-Namen für Port 80 durch "web" überschreiben
          - --entrypoints.web.address=:80
          # EntryPoint-Namen für Port 443 deklarieren
          - --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:
          # Der HTTP-Port
          - "80:80"
          # Der HTTPS-Port
          - "443:443"
          # Die Web-UI (aktiviert durch --api.insecure=true)
          - "8080:8080"
        volumes:        # Syntax --> Host-Standort:Pfad-im-Container
          # Damit Traefik auf Docker-Ereignisse hören kann
          - /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
          
       #Tiny Go-Webserver, der OS-Informationen und HTTP-Anfragen in die Ausgabe schreibt
    #  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
Meine Discourse app.yml befindet sich hier
## Dies ist die All-in-One, eigenständige Discourse Docker-Container-Vorlage
##
## Nach Änderungen an dieser Datei MUSST du neu aufbauen
## /var/discourse/launcher rebuild app
##
## SEHR VORSICHTIG BEIM BEARBEITEN!
## YAML-DATEIEN SIND EXTREM EMPFINDLICH GEGENÜBER FEHLERN IN LEERZEICHEN ODER AUSRICHTUNG!
## Besuche http://www.yamllint.com/, um diese Datei bei Bedarf zu validieren

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Kommentiere diese beiden Zeilen aus, wenn du Lets Encrypt (https) hinzufügen möchtest
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## Welche TCP/IP-Ports sollte dieser Container freigeben?
## Wenn du möchtest, dass Discourse einen Port mit einem anderen Webserver wie Apache oder nginx teilt,
## siehe https://meta.discourse.org/t/17247 für Details
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Setze db_shared_buffers auf maximal 25% des gesamten Speichers.
  ## wird automatisch vom Bootstrap basierend auf dem erkannten RAM gesetzt, oder du kannst es überschreiben
  db_shared_buffers: "128MB"

  ## kann die Sortierleistung verbessern, erhöht aber die Speichernutzung pro Verbindung
  #db_work_mem: "40MB"

  ## Welche Git-Revision soll dieser Container verwenden? (Standard: 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

  ## Wie viele gleichzeitige Webanfragen werden unterstützt? Hängt vom Speicher und den CPU-Kernen ab.
  ## wird automatisch vom Bootstrap basierend auf den erkannten CPUs gesetzt, oder du kannst es überschreiben
  UNICORN_WORKERS: 2

  ## TODO: Der Domainname, auf den diese Discourse-Instanz antworten soll
  ## Erforderlich. Discourse funktioniert nicht mit einer reinen IP-Nummer.
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## Kommentiere dies aus, wenn du möchtest, dass der Container mit demselben
  ## Hostnamen (-h-Option) wie oben angegeben gestartet wird (Standard "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Liste der durch Kommas getrennten E-Mail-Adressen, die bei der ersten Registrierung als Admin und Entwickler festgelegt werden
  ## Beispiel 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'discourse@myemail.com'

  ## TODO: Der SMTP-Mailserver, der zur Validierung neuer Konten und zum Senden von Benachrichtigungen verwendet wird
  # SMTP-Adresse, Benutzername und Passwort sind erforderlich
  # WARNUNG: Das Zeichen '#' im SMTP-Passwort kann Probleme verursachen!
  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           # (optional, Standard true)

  ## Wenn du die Lets Encrypt-Vorlage hinzugefügt hast, kommentiere unten aus, um ein kostenloses SSL-Zertifikat zu erhalten
  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## Die http- oder https-CDN-Adresse für diese Discourse-Instanz (konfiguriert zum Abrufen)
  ## siehe https://meta.discourse.org/t/14857 für Details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
## Der Docker-Container ist zustandslos; alle Daten werden in /shared gespeichert
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins gehen hier hin
## siehe https://meta.discourse.org/t/19157 für Details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Beliebige benutzerdefinierte Befehle, die nach dem Build ausgeführt werden sollen
run:
  - exec: echo "Beginn der benutzerdefinierten Befehle"
  ## Wenn du die 'Von'-E-Mail-Adresse für deine erste Registrierung festlegen möchtest, kommentiere dies aus und ändere es:
  ## Nach Erhalt der ersten Anmelde-E-Mail diesen Zeilenkommentar wieder setzen. Dies muss nur einmal ausgeführt werden.
  - exec: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "Ende der benutzerdefinierten Befehle"

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
Entschuldigt bitte das direkte Taggen, aber es scheint, als wärt ihr die einzigen dokumentierten Nutzer, die Discourse hinter Traefik betreiben.
Obwohl Traefik verspricht, sich um alles zu kümmern, scheint die Einrichtung doch nicht so einfach zu sein.
Bisher war ich leider nicht erfolgreich:

Funktionsfähige URLs:
Nicht funktionsfähige URL:

Ich wäre euch sehr dankbar, wenn ihr die vollständige Konfiguration von Discourse und Traefik teilen könntet, damit ich die Problemanalyse besser durchführen kann.

Meine Traefik-Konfigurationen finden sich am Ende dieses Beitrags: Endless 502 / forwarding when calling dashboard via subdomain #6123 - #9 by PackElend - Traefik v2 - Traefik Labs Community Forum

Da ich nur auf meinem Handy bin, bitte ich euch, meine Konfiguration hier zu prüfen: traefik - SeAT Discourse Documentation

Bitte beachtet: Ich habe es nur mit den Versionen 1.6 und 1.7 von Traefik zum Laufen gebracht. Ich habe keine Ahnung, ob das mit Version 2 funktionieren wird.

Damit konnten mehrere Benutzer mein Plugin nutzen, Discourse verwenden und Traefik betreiben.

Hinweis: Ich habe keinen einzigen Beitrag in diesem Thread gelesen; ich antworte einfach auf den Ping.

Vielen Dank :slight_smile: :partying_face:

Ich werde versuchen, es von v1 auf v2 zu übertragen.

Ich habe bereits eine grobe Idee, brauche aber noch ein paar Stunden, um alles durchzudenken.

Ich gehe davon aus, dass die Templates für SSL und Let’s Encrypt auskommentiert sind, sodass der Template-Abschnitt so aussieht:

    templates:
          - "templates/postgres.template.yml"
          - "templates/redis.template.yml"
          - "templates/web.template.yml"
          - "templates/web.ratelimited.template.yml"
        ## Kommentiere diese beiden Zeilen aus, wenn du Let's Encrypt (https) hinzufügen möchtest
          #- "templates/web.ssl.template.yml"
          #- "templates/web.letsencrypt.ssl.template.yml"

Ja, warum solltest du möchtest, dass der Discourse-Container deine SSL-Zertifikate verwaltet, wenn du ohnehin einen Proxy davor einrichten willst?

Bitte poste deine Lösung, sobald du fertig bist.

In Run other websites on the same machine as Discourse - #301 siehe:

Ich würde vorschlagen, den Template-Abschnitt auch in der Dokumentation aufzunehmen. Mir ist aufgefallen, dass er in meiner Installation nicht auskommentiert war, da ich zuerst eine Standalone-Installation durchgeführt habe, um die app.yml zu erhalten. Am Anfang habe ich vergessen, sie auszukommentieren. Das könnte verhindern, dass andere in dasselbe Problem geraten.

Klar.

Es wird dort doch nicht die statische Konfiguration von Traefik angezeigt, oder?

Gute Nachrichten, alle! http://forum.fairbnb.community/ ist erreichbar.

Dies ist die Konfiguration mit minimalen Änderungen in app.yml, um sie über http bereitzustellen. Am Wochenende werde ich mich mit https befassen.

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## Kommentiere diese beiden Zeilen aus, wenn du Lets Encrypt (https) hinzufügen möchtest
    #- "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

Für SSL konfigurieren Sie einfach Traefik + Let’s Encrypt, Sie müssen das SSL von Discourse nicht verwenden.

Traefik verwaltet die Verschlüsselung für alle Ihre Container.

Derzeit verwende ich Traefik 1.6, daher weiß ich noch nicht, wie man es in Traefik v2 aktiviert.

Ja, siehe Run other websites on the same machine as Discourse, aber es scheint, als erwartet Discourse bestimmte Header-Informationen, wenn der Client über HTTPS mit dem Proxy kommuniziert.

Ich habe mich kurz damit beschäftigt. Ich werde versuchen, es so zu erklären, dass es auch für den typischen 9-bis-5-Nutzer verständlich ist.

Ja, siehe auch Redirecting.... Am Anfang habe ich direkt mit HTTPS begonnen, und die Zertifikatserstellung war erfolgreich, aber das war’s auch schon. Jetzt muss ich das mit dem Wissen, das ich seitdem gesammelt habe, in Einklang bringen.

Du nutzt also HTTPS, um dein Forum zu erreichen, oder?
Kannst du die Konfiguration von Traefik und Discourse teilen? Je mehr Informationen du bereitstellst, desto einfacher wird es für mich am Wochenende sein.
Die Anleitung zum Upgrade von V1 auf V2 findest du unter Redirecting..., aber ich werde versuchen, das am Wochenende hier zu erklären.

OK, dies ist meine traefik.toml, die für die neue Version v2 nicht gültig ist

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"

Teil der Discourse-Konfiguration

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

expose:
  - "80"   # http ------ nur Container-Ports exponieren
  - "443" # https ------ Sie müssen keinen externen Host-Port exponieren

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

Mit dieser Konfiguration leitet Traefik alle Anfragen von Port 80 “http” auf Port 443 “https” um. Aktivieren Sie FORCE HTTPS im Discourse-Admin-Bereich, um Fehler zu vermeiden.

@pfaffman, ich weiß nicht, ob die Benachrichtigung noch funktioniert, wenn ich deine Antwort in einem anderen Thema zitiere, daher markiere ich dich.

Deine Konfiguration sieht also wie die oben genannte aus, aber

und unter Verwendung von Umgebungsvariablen (dieser Ansatz wird in https://stackoverflow.com/questions/52804610/how-do-you-set-environmental-variables-for-traefik und https://blog.raveland.org/post/traefik_compose referenziert)

Also HTTPS funktioniert :partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
und ich glaube, ich habe verstanden, wie das alles funktioniert :slight_smile:. Ich werde versuchen, es in den kommenden Tagen aufzuschreiben.

Meine Konfiguration

Discourse app.yml-Auszug

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Kommentiere diese beiden Zeilen aus, wenn du Lets Encrypt (HTTPS) hinzufügen möchtest
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## Welche TCP/IP-Ports soll dieser Container freigeben?
## Wenn du Discourse mit einem anderen Webserver wie Apache oder nginx auf einem Port teilen möchtest,
## siehe https://meta.discourse.org/t/17247 für Details
expose:
  #- "80:80"   # HTTP
  #- "443:443" # HTTPS
  #- "80"      # HTTP
  #- "443"     # HTTPS
  #- "40080:80"
  #- "40443:443"

labels:
  app_name:                                                                     discourse

  #----Traefik-Labels------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       bridge_proxy_traefikv2

   #---HTTP-ROUTER-ABSCHNITT-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.fairbnb.community`)
    #--HTTP-ABSCHNITT--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  #traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---HTTPS-ROUTER-ABSCHNITT
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.fairbnb.community`)
    #--HTTPS-ABSCHNITT
  traefik.http.routers.discourse_secure.entrypoints:                            websecure
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--TLS-ABSCHNITT
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---MIDDLEWARE-ABSCHNITT: HTTP zu HTTPS umleiten
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Traefik-Statische Konfiguration

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: {}

Hallo,

ich habe diesen Beitrag als Anleitung verwendet, um Discourse so einzurichten, dass es mit Traefik funktioniert. Ich habe Traefik bereits mit einer anderen Webanwendung in Betrieb.

Wenn ich die Seite forum.private.com aufrufe, erhalte ich einen Fehler „404 page not found“.

Etwas scheint zu funktionieren, denn im Traefik-Dashboard unter dem Reiter „Services“ kann ich discourse@docker und discourse_secure@docker sehen.

Allerdings gibt es im Reiter „Router“ nichts für Discourse.

Die Änderungen, die ich an der app.yml vorgenommen habe, sind hier aufgeführt und basieren größtenteils auf dem oben verlinkten Beitrag. Ich habe am Ende der Docker-Argumente einen exponierten Port hinzugefügt, was anscheinend die oben genannten Dienste freigegeben hat. Ich wäre für jede Hilfe dankbar!

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 ist der Port, auf dem das Dashboard läuft
      - "443:443" # <== https
    command:
    #### Dies sind die CLI-Befehle, die Traefik konfigurieren und ihm mitteilen, wie es arbeiten soll! ####

      - --api.insecure=true # <== Insecure-API aktivieren, NICHT FÜR PRODUKTIONSEINSATZ EMPFOHLEN
      - --api.dashboard=true # <== Dashboard aktivieren, um Dienste, Middleware, Router usw. anzuzeigen
      - --api.debug=true # <== Zusätzliche Endpunkte für Debugging und Profiling aktivieren
      ## Log-Einstellungen (Optionen: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
      - --log.level=DEBUG # <== Log-Level von Traefik festlegen
      ## Provider-Einstellungen - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== Docker als Provider für Traefik aktivieren
      - --providers.docker.exposedbydefault=false # <== Nicht jeden Container standardmäßig für Traefik exponieren, nur die aktivierten
      - --providers.file.filename=/dynamic.yaml # <== Auf eine dynamische Konfigurationsdatei verweisen
      - --providers.docker.network=web # <== Auf dem Docker-Netzwerk namens web operieren
      ## Entry-Point-Einstellungen - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== Einen Entry-Point für Port :80 namens web definieren
      - --entrypoints.web-secured.address=:443 # <== Einen Entry-Point für HTTPS auf Port :443 namens web-secured definieren
      ## Zertifikat-Einstellungen (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== TLS-ALPN-01 aktivieren, um ACME-Zertifikate zu generieren und zu erneuern
      - --certificatesresolvers.mytlschallenge.acme.email=private@private.com # <== E-Mail für Zertifikate festlegen
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== ACME-Datei zum Speichern von Zertifikatsinformationen definieren
    volumes:
      - ./letsencrypt:/letsencrypt # <== Volume für Zertifikate (TLS)
      - /var/run/docker.sock:/var/run/docker.sock # <== Volume für Docker-Admin
      - ./dynamic.yaml:/dynamic.yaml # <== Volume für dynamische Konfigurationsdatei, **Referenz: Zeile 27
    networks:
      - web # <== Traefik auf dem Netzwerk namens web platzieren, um Container auf diesem Netzwerk zu erreichen
    labels:
    #### Labels definieren das Verhalten und die Regeln des Traefik-Proxys für diesen Container ####
      - "traefik.enable=true" # <== Traefik auf sich selbst aktivieren, um das Dashboard anzuzeigen und eine Subdomain zuzuweisen
      - "traefik.http.routers.api.rule=Host(`monitor.private.com`)" # <== Domain für das Dashboard festlegen
      - "traefik.http.routers.api.service=api@internal" # <== API als Dienst zum Zugriff aktivieren


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

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

Discourse app.yml
## Dies ist die All-in-One, eigenständige Discourse Docker-Container-Vorlage
##
## Nach Änderungen an dieser Datei MUSS neu aufgebaut werden
## /var/discourse/launcher rebuild app
##
## SEI *SEHR* VORSICHTIG BEI DER BEARBEITUNG!
## YAML-DATEIEN SIND EXTREM EMPFINDLICH GEGENÜBER FEHLERN IN LEERZEICHEN ODER AUSRICHTUNG!
## Besuchen Sie http://www.yamllint.com/, um diese Datei bei Bedarf zu validieren

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Kommentieren Sie diese beiden Zeilen aus, wenn Sie Lets Encrypt (https) hinzufügen möchten
  #- "templates/web.ssl.template.yml"
  # "templates/web.letsencrypt.ssl.template.yml"

## Welche TCP/IP-Ports sollen von diesem Container exponiert werden?
## Wenn Sie Discourse einen Port mit einem anderen Webserver wie Apache oder nginx teilen möchten,
## siehe https://meta.discourse.org/t/17247 für Details
expose:
  #- "80:80"   # http
  #- "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Setzen Sie db_shared_buffers auf maximal 25 % des gesamten Arbeitsspeichers.
  ## Wird automatisch vom Bootstrap basierend auf dem erkannten RAM festgelegt, oder Sie können es überschreiben
  db_shared_buffers: "128MB"

  ## Kann die Sortierleistung verbessern, erhöht aber den Speicherverbrauch pro Verbindung
  #db_work_mem: "40MB"

  ## Welche Git-Revision soll dieser Container verwenden? (Standard: tests-passed)
  #version: tests-passed

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

  ## Wie viele gleichzeitige Webanfragen werden unterstützt? Hängt von Speicher und CPU-Kernen ab.
  ## Wird automatisch vom Bootstrap basierend auf den erkannten CPUs festgelegt, oder Sie können es überschreiben
  UNICORN_WORKERS: 2

  ## TODO: Der Domainname, auf den diese Discourse-Instanz antworten soll
  ## Erforderlich. Discourse funktioniert nicht mit einer reinen IP-Nummer.
  DISCOURSE_HOSTNAME: forum.private.com

  ## Kommentieren Sie dies aus, wenn Sie möchten, dass der Container mit demselben
  ## Hostnamen (-h-Option) wie oben angegeben gestartet wird (Standard "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Liste der durch Komma getrennten E-Mails, die bei der ersten Anmeldung als Admin und Entwickler hinzugefügt werden
  ## Beispiel: 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'private@private.com'

  ## TODO: Der SMTP-Mailserver, der zur Validierung neuer Konten und zum Senden von Benachrichtigungen verwendet wird
  ## SMTP-Adresse, Benutzername und Passwort sind erforderlich
  # WARNUNG: Das Zeichen '#' im SMTP-Passwort kann Probleme verursachen!
  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           # (optional, Standard true)

  ## Wenn Sie die Lets-Encrypt-Vorlage hinzugefügt haben, kommentieren Sie unten aus, um ein kostenloses SSL-Zertifikat zu erhalten
  LETSENCRYPT_ACCOUNT_EMAIL: private@private.com

  ## Die HTTP- oder HTTPS-CDN-Adresse für diese Discourse-Instanz (konfiguriert zum Abrufen)
  ## siehe https://meta.discourse.org/t/14857 für Details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Der Docker-Container ist zustandslos; alle Daten werden in /shared gespeichert
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins gehen hier
## siehe https://meta.discourse.org/t/19157 für Details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Beliebige benutzerdefinierte Befehle, die nach dem Build ausgeführt werden sollen
run:
  - exec: echo "Beginn der benutzerdefinierten Befehle"
  ## Wenn Sie die 'Von'-E-Mail-Adresse für Ihre erste Registrierung festlegen möchten, kommentieren Sie dies aus und ändern Sie:
  ## Nach Erhalt der ersten Anmelde-E-Mail kommentieren Sie die Zeile erneut aus. Sie muss nur einmal ausgeführt werden.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Ende der benutzerdefinierten Befehle"

labels:
  app_name:                                                                     discourse

  #----Traefik-Labels------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       web

   #---HTTP-ROUTER-ABSCHNITT-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.private.com`)
    #--HTTP-ABSCHNITT--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---HTTPS-ROUTER-ABSCHNITT
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.private.com`)
    #--HTTPS-ABSCHNITT
  traefik.http.routers.discourse_secure.entrypoints:                            web-secured
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--TLS-ABSCHNITT
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---MIDDLEWARE-ABSCHNITT: HTTP zu HTTPS umleiten
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Vielen Dank