Discorso con 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.

Ciao,
puoi condividere la tua configurazione di Traefik?

Finisco con un 302, reindirizzamento automatico a HTTPS e poi si ferma…
La dashboard di Traefik dice che tutto è ok.

il mio docker-compose.yml è qui
version: "3.7"
    services:
      traefik-reverse-proxy:   
        # L'immagine ufficiale Docker di Traefik v2.0
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # dice a Traefik di ascoltare Docker 
          - --providers.docker          # (Default: true)
          # Abilita api/dashboard / (imposta l'endpoint Docker per comunicare con l'API di Docker)
          - --api=true                    # (Default: false)
          # Attiva la dashboard. 
          - --api.dashboard               # (Default: true)
          # Abilita l'interfaccia web / Traefik ascolterà sulla porta 8080 di default per le richieste API. / Attiva l'API direttamente sull'entryPoint chiamato traefik. (Default: false) --> porta '8080'v= entryPoint 'traefik', sovrascrive --api
          - --api.insecure=true         # (Default: false) 
          # Abilita endpoint aggiuntivi per debug e profilazione. 
          - --api.debug=true            # (Default: false)
          # imposta il livello di debug del log
          - --log.level=DEBUG    
          # scrittura dell'accesslog
          - --accesslog=true    
          # definisce la posizione di archiviazione all'interno del container, il file di log viene scritto all'interno del container. Per renderlo disponibile sull'host viene montato, vedi la sezione volumes
          - --log.filePath=/var/traefik-container/logs/traefik-log.log
          - --accesslog.filepath=/var/traefik-container/logs/traefik-access.log
          # sovrascrive il nome dell'entrypoint della porta 80 di default con "web"
          - --entrypoints.web.address=:80
          # dichiara il nome dell'entrypoint per la porta 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:
          # La porta HTTP
          - "80:80"
          # La porta HTTPS
          - "443:443"
          # L'interfaccia web (abilitata da --api.insecure=true)
          - "8080:8080"
        volumes:        # sintassi --> posizione-host:percorso-nel-container
          # In modo che Traefik possa ascoltare gli eventi 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
          
       #Tiny Go webserver che stampa informazioni sul sistema operativo e richieste HTTP all'output
    #  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
il mio app.yml di Discourse è qui
## questo è il template del container Docker standalone all-in-one di Discourse
##
## Dopo aver apportato modifiche a questo file, DEVI ricostruire
## /var/discourse/launcher rebuild app
##
## FAI MOLTA ATTENZIONE QUANDO MODIFICHI!
## I FILE YAML SONO MOLTO MOLTO SENSIBILI A ERRORI NELLO SPAZIATURA O NELL'ALLINEAMENTO!
## visita http://www.yamllint.com/ per validare questo file quando necessario

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Scommenta queste due righe se desideri aggiungere Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## quali porte TCP/IP deve esporre questo container?
## Se vuoi che Discourse condivida una porta con un altro web server come Apache o nginx,
## vedi https://meta.discourse.org/t/17247 per i dettagli
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Imposta db_shared_buffers al massimo al 25% della memoria totale.
  ## verrà impostato automaticamente da bootstrap in base alla RAM rilevata, oppure puoi sovrascrivere
  db_shared_buffers: "128MB"

  ## può migliorare le prestazioni di ordinamento, ma aumenta l'uso di memoria per connessione
  #db_work_mem: "40MB"

  ## Quale revisione Git dovrebbe usare questo container? (default: 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

  ## Quante richieste web simultanee sono supportate? Dipende dalla memoria e dai core della CPU.
  ## verrà impostato automaticamente da bootstrap in base alle CPU rilevate, oppure puoi sovrascrivere
  UNICORN_WORKERS: 2

  ## TODO: Il nome di dominio a cui risponderà questa istanza di Discourse
  ## Obbligatorio. Discourse non funzionerà con un semplice numero IP.
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## Scommenta se vuoi che il container venga avviato con lo stesso
  ## nome host (opzione -h) specificato sopra (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Elenco di email separate da virgola che saranno rese amministratori e sviluppatori
  ## all'iscrizione iniziale esempio 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'discourse@myemail.com'

  ## TODO: Il server SMTP utilizzato per validare nuovi account e inviare notifiche
  ## INDIRIZZO SMTP, nome utente e password sono obbligatori
  # ATTENZIONE: il carattere '#' nella password SMTP può causare problemi!
  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           # (opzionale, default true)

  ## Se hai aggiunto il template Lets Encrypt, scommenta qui sotto per ottenere un certificato SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## L'indirizzo CDN http o https per questa istanza di Discourse (configurato per recuperare)
  ## vedi https://meta.discourse.org/t/14857 per i dettagli
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
## Il container Docker è stateless; tutti i dati sono archiviati in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## I plugin vanno qui
## vedi https://meta.discourse.org/t/19157 per i dettagli
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Qualsiasi comando personalizzato da eseguire dopo la costruzione
run:
  - exec: echo "Inizio dei comandi personalizzati"
  ## Se vuoi impostare l'indirizzo email 'From' per la tua prima registrazione, scommenta e modifica:
  ## Dopo aver ricevuto la prima email di iscrizione, rimetti il commento alla riga. Deve essere eseguito solo una volta.
  - exec: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "Fine dei comandi personalizzati"

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
Scusate se vi taggo direttamente, ma sembra che siate gli unici utenti documentati che eseguono Discourse dietro Traefik.
Nonostante le promesse che Traefik si occupi di tutto, sembra non essere così semplice da configurare.
Finora non sono riuscito a farlo funzionare:

URL funzionanti:
URL non funzionante:

Apprezzerei molto se poteste condividere la configurazione completa di Discourse e Traefik, per consentirmi di effettuare una risoluzione dei problemi più efficace.

Le mie configurazioni di Traefik alla fine di questo post: Endless 502 / forwarding when calling dashboard via subdomain #6123 - #9 by PackElend - Traefik v2 - Traefik Labs Community Forum

Dato che sono solo su mobile, controllate la mia configurazione qui: traefik - SeAT Discourse Documentation

Nota: l’ho fatto funzionare solo con le versioni 1.6 e 1.7 di Traefik. Non so se funzionerà con la v2.

Grazie a ciò, più utenti hanno potuto utilizzare il mio plugin, Discourse e Traefik.

Nota: non ho letto un singolo post in questo thread, rispondo semplicemente al ping.

Grazie mille :slight_smile: :partying_face:

Proverò a tradurlo dalla v1 alla v2.

Sto già prendendo un’idea, ho bisogno di qualche ora per rifletterci.

Immagino che i template per SSL e Let’s Encrypt siano commentati, quindi la sezione template appare così:

    templates:
          - "templates/postgres.template.yml"
          - "templates/redis.template.yml"
          - "templates/web.template.yml"
          - "templates/web.ratelimited.template.yml"
        ## Scommenta queste due righe se vuoi aggiungere Let's Encrypt (https)
          #- "templates/web.ssl.template.yml"
          #- "templates/web.letsencrypt.ssl.template.yml"

Sì, perché vorresti che il contenitore Discourse gestisse i tuoi certificati SSL se stai per attivare un proxy davanti?

Per favore, pubblica la tua soluzione non appena avrai finito.

in Run other websites on the same machine as Discourse - #301 vedi

Suggerirei di aggiungere anche la sezione del template nella documentazione. Ho notato che nel mio install non era commentata, poiché ho prima fatto un’installazione standalone per ottenere l’app.yml. All’inizio ho dimenticato di commentarle. Questo potrebbe evitare che altri incorrano nello stesso problema.

certo

Non mostra la configurazione statica di Traefik, vero?

Buone notizie a tutti! http://forum.fairbnb.community/ è raggiungibile.

Questa è la configurazione con le modifiche minime in app.yml per renderla accessibile via http; approfondirò l’uso di https nel weekend.

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## Decommenta queste due righe se desideri aggiungere 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

Per SSL, configura semplicemente Traefik + Let’s Encrypt: non è necessario utilizzare il SSL di Discourse.

Traefik gestirà la crittografia per tutti i tuoi container.

Attualmente sto utilizzando Traefik 1.6, quindi non so ancora come abilitarlo su Traefik v2.

Sì, vedi Run other websites on the same machine as Discourse, ma sembra che Discourse si aspetti certe informazioni negli header quando il client comunica con il proxy tramite HTTPS.

Ho dato un’occhiata veloce. Cercherò di tradurlo in un linguaggio comprensibile anche all’utente medio che lavora dalle 9 alle 17.

Sì, vedi anche su Redirecting.... All’inizio ho iniziato subito con HTTPS e la creazione del certificato è andata a buon fine, ma solo fino a quel punto. Ora devo allinearla con le conoscenze che ho acquisito da allora.

Quindi usi HTTPS per accedere al tuo forum, giusto?
Puoi condividere la configurazione di Traefik e Discourse? Più informazioni condividi, più mi sarà facile aiutarti nel weekend.
La guida per la migrazione da v1 a v2 è disponibile su Redirecting..., ma proverò a spiegarla qui nel weekend.

OK, questo è il mio traefik.toml, non valido per la nuova versione 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"

parte della configurazione di Discourse

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

expose:
  - "80"   # http ------ basta esporre le porte del contenitore
  - "443" # https ------ non è necessario esporre la porta dell'host esterna

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

con questa configurazione traefik reindirizza tutte le richieste dalla porta 80 “http” alla porta 443 “https”,
abilita FORZA HTTPS nel pannello di amministrazione di Discourse per evitare errori.

@pfaffman, non so se le notifiche funzionino ancora se cito la tua risposta in un altro argomento, quindi ti taggo.

Quindi la tua configurazione sembra quella sopra, ma

e utilizzando le variabili d’ambiente (questo approccio è citato in https://stackoverflow.com/questions/52804610/how-do-you-set-environmental-variables-for-traefik e https://blog.raveland.org/post/traefik_compose)

quindi https funziona :partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
e credo di aver capito come funziona tutto questo :slight_smile:. Cercherò di scriverlo nei prossimi giorni

la mia configurazione

estratto app.yml di discourse

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Scommenta queste due righe se desideri aggiungere Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## quali porte TCP/IP deve esporre questo contenitore?
## Se desideri che Discourse condivida una porta con un altro server web come Apache o nginx,
## vedi https://meta.discourse.org/t/17247 per i dettagli
expose:
  #- "80:80"   # http
  #- "443:443" # https
  #- "80"      # http
  #- "443"     # https
  #- "40080:80"
  #- "40443:443"

labels:
  app_name:                                                                     discourse

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

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

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

   #---SEZIONE MIDDLEWARE reindirizza http a https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Configurazione statica di 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: {}

Saluti,

Ho utilizzato questo post come guida per configurare Discourse in modo che funzioni con Traefik. Ho già configurato Traefik per un’altra applicazione web.

Quando visito forum.private.com, ricevo un errore “404 pagina non trovata”.

Sembra che qualcosa stia funzionando, perché nella dashboard di Traefik, nella scheda Servizi, vedo discourse@docker e discourse_secure@docker.

Tuttavia, nella scheda Router non c’è nulla relativo a Discourse.

Le modifiche apportate al file app.yml sono riportate qui di seguito, basate in gran parte sul post collegato sopra. Ho aggiunto una porta esposta negli argomenti Docker alla fine, il che sembra aver reso visibili i servizi menzionati. Apprezzerei qualsiasi aiuto!

Traefik docker-compose
version: "3.3"

services:
  ################################################
  ####        Impostazione Proxy Traefik          #####
  ###############################################
  traefik:
    image: traefik:v2.0
    restart: always
    container_name: traefik
    ports:
      - "80:80" # <== http
      - "8080:8080" # <== :8080 è dove viene eseguito la dashboard
      - "443:443" # <== https
    command:
    #### Questi sono i comandi CLI che configureranno Traefik e gli diranno come funzionare! ####

      - --api.insecure=true # <== Abilitazione API non sicura, NON CONSIGLIATA PER LA PRODUZIONE
      - --api.dashboard=true # <== Abilitazione della dashboard per visualizzare servizi, middleware, router, ecc...
      - --api.debug=true # <== Abilitazione di endpoint aggiuntivi per il debug e il profiling
      ## Impostazioni Registro (opzioni: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
      - --log.level=DEBUG # <== Impostazione del livello dei log da Traefik
      ## Impostazioni Provider - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== Abilitazione di Docker come provider per Traefik
      - --providers.docker.exposedbydefault=false # <== Non esporre ogni contenitore a Traefik, esporre solo quelli abilitati
      - --providers.file.filename=/dynamic.yaml # <== Riferimento a un file di configurazione dinamico
      - --providers.docker.network=web # <== Operare sulla rete Docker denominata web
      ## Impostazioni Point di ingresso - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== Definizione di un punto di ingresso per la porta :80 denominata web
      - --entrypoints.web-secured.address=:443 # <== Definizione di un punto di ingresso per https sulla porta :443 denominata web-secured
      ## Impostazioni Certificati (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== Abilitazione TLS-ALPN-01 per generare e rinnovare certificati ACME
      - --certificatesresolvers.mytlschallenge.acme.email=private@private.com # <== Impostazione email per i certificati
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== Definizione del file ACME per memorizzare le informazioni sui certificati
    volumes:
      - ./letsencrypt:/letsencrypt # <== Volume per i certificati (TLS)
      - /var/run/docker.sock:/var/run/docker.sock # <== Volume per l'amministrazione Docker
      - ./dynamic.yaml:/dynamic.yaml # <== Volume per il file di configurazione dinamico, **rif: riga 27
    networks:
      - web # <== Posizionamento di Traefik sulla rete denominata web, per accedere ai contenitori su questa rete
    labels:
    #### I label definiscono il comportamento e le regole del proxy Traefik per questo contenitore ####
      - "traefik.enable=true" # <== Abilitazione di Traefik su se stesso per visualizzare la dashboard e assegnare un sottodominio per visualizzarla
      - "traefik.http.routers.api.rule=Host(`monitor.private.com`)" # <== Impostazione del dominio per la dashboard
      - "traefik.http.routers.api.service=api@internal" # <== Abilitazione dell'API come servizio accessibile


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

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

Discourse app.yml
## questo è il template del contenitore Docker Discourse standalone all-in-one
##
## Dopo aver apportato modifiche a questo file, DOVETE ricostruire
## /var/discourse/launcher rebuild app
##
## SIATE *MOLTO* CAUTI DURANTE LA MODIFICA!
## I FILE YAML SONO SUPER SUPER SENSIBILI A ERRORI NELLO SPAZIO O NELL'ALLINEAMENTO!
## visitate http://www.yamllint.com/ per convalidare questo file quando necessario

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Scommentate queste due righe se desiderate aggiungere Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  # "templates/web.letsencrypt.ssl.template.yml"

## quali porte TCP/IP dovrebbe esporre questo contenitore?
## Se desiderate che Discourse condivida una porta con un altro server web come Apache o nginx,
## consultate https://meta.discourse.org/t/17247 per i dettagli
expose:
  #- "80:80"   # http
  #- "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Impostate db_shared_buffers a un massimo del 25% della memoria totale.
  ## verrà impostato automaticamente da bootstrap in base alla RAM rilevata, oppure potete sovrascriverlo
  db_shared_buffers: "128MB"

  ## può migliorare le prestazioni di ordinamento, ma aumenta l'uso di memoria per connessione
  #db_work_mem: "40MB"

  ## Quale revisione Git dovrebbe utilizzare questo contenitore? (predefinito: tests-passed)
  #version: tests-passed

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

  ## Quante richieste web simultanee sono supportate? Dipende dalla memoria e dai core della CPU.
  ## verrà impostato automaticamente da bootstrap in base alle CPU rilevate, oppure potete sovrascriverlo
  UNICORN_WORKERS: 2

  ## TODO: Il nome di dominio a cui risponderà questa istanza di Discourse
  ## Obbligatorio. Discourse non funzionerà con un semplice numero IP.
  DISCOURSE_HOSTNAME: forum.private.com

  ## Scommentate se desiderate che il contenitore venga avviato con lo stesso
  ## nome di host (-h option) specificato sopra (predefinito "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Elenco di email separate da virgola che diventeranno amministratori e sviluppatori
  ## al primo esempio di registrazione 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'private@private.com'

  ## TODO: Il server SMTP utilizzato per validare nuovi account e inviare notifiche
  ## INDIRIZZO SMTP, nome utente e password sono obbligatori
  # ATTENZIONE: il carattere '#' nella password SMTP può causare problemi!
  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           # (opzionale, predefinito true)

  ## Se avete aggiunto il template Lets Encrypt, scommentate qui sotto per ottenere un certificato SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: private@private.com

  ## L'indirizzo http o https CDN per questa istanza di Discourse (configurato per il recupero)
  ## consultate https://meta.discourse.org/t/14857 per i dettagli
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Il contenitore Docker è senza stato; tutti i dati sono archiviati in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## I plugin vanno qui
## consultate https://meta.discourse.org/t/19157 per i dettagli
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Qualsiasi comando personalizzato da eseguire dopo la costruzione
run:
  - exec: echo "Inizio dei comandi personalizzati"
  ## Se desiderate impostare l'indirizzo email 'From' per la vostra prima registrazione, scommentate e modificate:
  ## Dopo aver ricevuto la prima email di registrazione, riscommentate la riga. Deve essere eseguita solo una volta.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Fine dei comandi personalizzati"

labels:
  app_name:                                                                     discourse

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

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

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

   #---SEZIONE MIDDLEWARE reindirizza http a https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Grazie