Discutindo com o Traefik 2.0

Olá a todos,

Estou migrando para um novo servidor e quero usar o Traefik 2.0 como proxy reverso. Estou com dificuldades na nova configuração. Adicionei uma seção no final do arquivo app.yml. (Fonte: 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"

Isso não parece estar funcionando. Quando abro a rota, recebo um erro Bad Gateway. Quando acesso diretamente o ip_adress:8060, o Discourse abre.

Alguém tem experiência com o Traefik 2.0?

Obrigado!

Depois de algumas tentativas, consegui resolver por conta própria.

Para referência futura, anexo meu app.yml:

...

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomente estas duas linhas se desejar adicionar o Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  #- "templates/web.socketed.template.yml" 

## quais portas TCP/IP este contêiner deve expor?
## Se quiser que o Discourse compartilhe uma porta com outro servidor web como Apache ou nginx,
## consulte https://meta.discourse.org/t/17247 para detalhes
#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"

Por que é necessário usar docker_args? De acordo com GitHub - discourse/discourse_docker: A Docker image for Discourse · GitHub, deveria funcionar assim:

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

Adicione rótulos ao contêiner atual. O exemplo acima adicionará --l monitor=true -l app_name=dev_discourse às opções ao executar o contêiner.

Além disso, onde docker_args é explicado?

@Cameron_D
como você descobriu que docker_args é o caminho a seguir?

Eu simplesmente não consegui fazer a seção de rótulos funcionar como esperado. Não tenho certeza do motivo exato pelo qual parou de funcionar, nem se foi corrigido desde então, pois deixei minha configuração exatamente como estava, já que está funcionando.

Olá,

você poderia compartilhar sua configuração do Traefik?

Estou recebendo um redirecionamento 302, que redireciona automaticamente para HTTPS e depois para… nada.
O painel do Traefik diz que está tudo ok.

meu docker-compose.yml está aqui
version: "3.7"
    services:
      traefik-reverse-proxy:   
        # A imagem oficial do Docker do Traefik v2.0
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # dizer ao Traefik para ouvir o Docker 
          - --providers.docker          # (Padrão: true)
          # Habilitar API/painel / (definir o endpoint do Docker para comunicar com a API do Docker)
          - --api=true                    # (Padrão: false)
          # Ativar painel. 
          - --api.dashboard               # (Padrão: true)
          # Habilitar a interface web / O Traefik ouvirá na porta 8080 por padrão para solicitações da API. / Ativar a API diretamente no entryPoint chamado traefik. (Padrão: false) --> porta '8080'v= entryPoint 'traefik', substitui --api
          - --api.insecure=true         # (Padrão: false) 
          # Habilitar endpoints adicionais para depuração e profiling. 
          - --api.debug=true            # (Padrão: false)
          # definir o nível de depuração do log
          - --log.level=DEBUG    
          # gravar o accesslog
          - --accesslog=true    
          # definir o local de armazenamento dentro do contêiner, o arquivo de log é gravado dentro do contêiner. Para torná-lo disponível no host, ele é montado, veja a seção volumes
          - --log.filePath=/var/traefik-container/logs/traefik-log.log
          - --accesslog.filepath=/var/traefik-container/logs/traefik-access.log
          # substituir o nome do entryPoint padrão da porta 80 por "web"
          - --entrypoints.web.address=:80
          # declarar o nome do entryPoint para a 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:
          # A porta HTTP
          - "80:80"
          # A porta HTTPS
          - "443:443"
          # A interface web (habilitada por --api.insecure=true)
          - "8080:8080"
        volumes:        # sintaxe --> local-no-host:caminho-no-contêiner
          # Para que o Traefik possa ouvir os eventos do 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 que imprime informações do sistema operacional e requisições HTTP na saída
    #  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
meu app.yml do Discourse está aqui
## este é o template do contêiner Docker standalone all-in-one do Discourse
##
## Após fazer alterações neste arquivo, você DEVE reconstruir
## /var/discourse/launcher rebuild app
##
## TENHA *MUITO* CUIDADO AO EDITAR!
## ARQUIVOS YAML SÃO SUPER SENSÍVEIS A ERROS EM ESPAÇOS EM BRANCO OU ALINHAMENTO!
## visite http://www.yamllint.com/ para validar este arquivo conforme necessário

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomente estas duas linhas se desejar adicionar Let's Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## quais portas TCP/IP este contêiner deve expor?
## Se você quiser que o Discourse compartilhe uma porta com outro servidor web como Apache ou nginx,
## veja https://meta.discourse.org/t/17247 para detalhes
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Defina db_shared_buffers para no máximo 25% da memória total.
  ## será definido automaticamente pelo bootstrap com base na RAM detectada, ou você pode substituir
  db_shared_buffers: "128MB"

  ## pode melhorar o desempenho de ordenação, mas aumenta o uso de memória por conexão
  #db_work_mem: "40MB"

  ## Qual revisão do Git este contêiner deve usar? (padrão: 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

  ## Quantas requisições web simultâneas são suportadas? Depende da memória e dos núcleos da CPU.
  ## será definido automaticamente pelo bootstrap com base nas CPUs detectadas, ou você pode substituir
  UNICORN_WORKERS: 2

  ## TODO: O nome de domínio ao qual esta instância do Discourse responderá
  ## Obrigatório. O Discourse não funcionará com um número IP puro.
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## Descomente se quiser que o contêiner seja iniciado com o mesmo
  ## nome de hostname (-h option) especificado acima (padrão "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Lista de e-mails separados por vírgula que serão administradores e desenvolvedores
  ## no cadastro inicial, exemplo 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'discourse@myemail.com'

  ## TODO: O servidor SMTP usado para validar novas contas e enviar notificações
  # ENDEREÇO SMTP, usuário e senha são obrigatórios
  # AVISO: o caractere '#' na senha SMTP pode causar problemas!
  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           # (opcional, padrão true)

  ## Se você adicionou o template Let's Encrypt, descomente abaixo para obter um certificado SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## O endereço http ou https do CDN para esta instância do Discourse (configurado para buscar)
  ## veja https://meta.discourse.org/t/14857 para detalhes
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
## O contêiner Docker é stateless; todos os dados são armazenados em /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins vão aqui
## veja https://meta.discourse.org/t/19157 para detalhes
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Quaisquer comandos personalizados para executar após a construção
run:
  - exec: echo "Início dos comandos personalizados"
  ## Se você quiser definir o endereço de e-mail 'De' para seu primeiro registro, descomente e altere:
  ## Após receber o primeiro e-mail de cadastro, comente novamente a linha. Ela só precisa ser executada uma vez.
  - exec: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "Fim dos comandos personalizados"

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
Peço desculpas por marcá-los diretamente, mas parece que vocês são os únicos usuários documentados que estão executando o Discourse atrás do Traefik.
Apesar da promessa de que o Traefik cuidaria de tudo, parece que a configuração não é tão simples.
Até agora, não tive sucesso:

URLs funcionando:
URL não funcionando:

Agradeceria muito se vocês pudessem compartilhar a configuração completa do Discourse e do Traefik, permitindo que eu faça a solução de problemas de forma mais eficaz.

Minhas configurações do Traefik no final desta postagem: Endless 502 / forwarding when calling dashboard via subdomain #6123 - #9 by PackElend - Traefik v2 - Traefik Labs Community Forum

Como estou apenas no meu celular, por favor, verifique minha configuração aqui: traefik - SeAT Discourse Documentation

Observação: Eu só consegui fazê-lo funcionar com as versões 1.6 e 1.7 do Traefik. Não tenho ideia se isso funcionará com a versão 2.

Com isso, vários usuários puderam usar meu plugin, o Discourse e o Traefik.

Nota: Não li nenhuma postagem nesta thread; estou apenas respondendo ao ping.

Muito obrigado :slight_smile: :partying_face:

Vou tentar traduzi-lo da versão v1 para a v2.

Já estou começando a ter uma ideia, preciso de algumas horas para refletir sobre isso.

Acho que os modelos para SSL e Let’s Encrypt estão comentados, então a seção de modelos fica assim:

    templates:
          - "templates/postgres.template.yml"
          - "templates/redis.template.yml"
          - "templates/web.template.yml"
          - "templates/web.ratelimited.template.yml"
        ## Descomente estas duas linhas se quiser adicionar o Let's Encrypt (https)
          #- "templates/web.ssl.template.yml"
          #- "templates/web.letsencrypt.ssl.template.yml"

Sim, por que você gostaria que o contêiner do Discourse gerencie seus certificados SSL, se você vai ativar um proxy na frente?

Por favor, publique sua solução assim que terminar.

Em Run other websites on the same machine as Discourse - #301 veja:

Sugiro adicionar a seção de modelos na documentação também. Notei que não estavam comentados na minha instalação, pois fiz primeiro a instalação standalone para obter o app.yml. No início, esqueci de comentá-los. Isso poderia evitar que outros enfrentem o mesmo problema.

Com certeza.

Isso não mostra a configuração estática do Traefik, certo?

Boas notícias, pessoal! http://forum.fairbnb.community/ está acessível.

Esta é a configuração com as mínimas alterações em app.yml para que seja servida via HTTP. Vou investigar o HTTPS no fim de semana.

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## Descomente estas duas linhas se desejar adicionar o 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

Para SSL, basta configurar o Traefik + Let’s Encrypt; você não precisa usar o SSL do Discourse.

O Traefik gerenciará a criptografia em todos os seus containers.

Atualmente, estou usando o Traefik 1.6, então ainda não sei como ativá-lo no Traefik v2.

Sim, veja Run other websites on the same machine as Discourse, mas parece que o Discourse espera certas informações de cabeçalho quando o cliente se comunica com o proxy via HTTPS.

Li rapidamente sobre isso. Vou tentar traduzir para um texto compreensível pelo usuário comum.

Sim, veja também em Redirecting.... No início, comecei diretamente com HTTPS e a criação do certificado foi bem-sucedida, mas só isso. Agora preciso alinhar isso com o conhecimento que adquiri desde então.

Então você usa HTTPS para acessar seu fórum, não é?
Você pode compartilhar a configuração do Traefik e do Discourse? Quanto mais for compartilhado, mais fácil será para mim no fim de semana.
O guia de migração da v1 para a v2 está em Redirecting..., mas tento explicar isso aqui no fim de semana.

OK, este é o meu traefik.toml, não válido para a nova versão v2

defaultEntryPoints = ["http", "https"]

[web]
address = ":8080"
  [web.auth.basic]
  users = ["seuusuario:suasenha"]

[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 da Configuração do Discourse

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

expose:
  - "80"   # http ------ apenas exponha as portas do contêiner 
  - "443" # https ------ você não precisa expor a porta do host externa

labels:
  traefik.port: '80'
  traefik.backend: 'nome_do_meu_contêiner'
  traefik.frontend.rule: 'Host:www.meuhost.com'
  traefik.docker.network: 'nome_da_minha_rede'
docker_args:
  - "--network=nome_da_minha_rede"

com essa configuração, o traefik redireciona todas as requisições da porta 80 “http” para a porta 443 “https”,
ative o FORÇAR HTTPS no painel de administração do Discourse para evitar erros.

@pfaffman, não sei se a notificação ainda funciona se eu citar sua resposta em outro tópico, então estou te marcando.

Então, sua configuração parece com a acima, mas

e usando variáveis de ambiente (essa abordagem é referenciada em https://stackoverflow.com/questions/52804610/how-do-you-set-environmental-variables-for-traefik e https://blog.raveland.org/post/traefik_compose)

Então HTTPS funciona :partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
E acho que entendi como tudo isso funciona :slight_smile:. Vou tentar escrever sobre isso nos próximos dias

Minha configuração

Extrato do app.yml do Discourse

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomente essas duas linhas se quiser adicionar o Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## Quais portas TCP/IP este contêiner deve expor?
## Se quiser que o Discourse compartilhe uma porta com outro servidor web, como Apache ou nginx,
## consulte https://meta.discourse.org/t/17247 para detalhes
expose:
  #- "80:80"   # http
  #- "443:443" # https
  #- "80"      # http
  #- "443"     # https
  #- "40080:80"
  #- "40443:443"

labels:
  app_name:                                                                     discourse

  #----Rótulos do Traefik------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       bridge_proxy_traefikv2

   #---SEÇÃO DE ROTAS HTTP-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.fairbnb.community`)
    #--SEÇÃO HTTP--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  #traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---SEÇÃO DE ROTAS HTTPS
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.fairbnb.community`)
    #--SEÇÃO HTTPS
  traefik.http.routers.discourse_secure.entrypoints:                            websecure
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--SEÇÃO TLS
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---SEÇÃO DE MIDDLEWARE redirecionar HTTP para HTTPS
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Configuração Estática do 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: {}

Olá,

Usei este post como guia para configurar o Discourse para funcionar com o Traefik. Já tenho o Traefik funcionando com outro aplicativo web.

Ao acessar forum.private.com, recebo um erro “404 página não encontrada”.

Parece que algo está funcionando, pois na aba Serviços do painel do Traefik, consigo ver discourse@docker e discourse_secure@docker.

No entanto, não há nada relacionado ao Discourse na aba Roteadores.

As alterações que fiz no app.yml estão abaixo, baseadas em grande parte no post linkado acima. Adicionei uma porta exposta nos argumentos do Docker no final, o que parece ter aberto os serviços mencionados acima. Agradeceria qualquer ajuda!

Traefik docker-compose
version: "3.3"

services:
  ################################################
  ####        Configuração do Proxy Traefik           #####
  ###############################################
  traefik:
    image: traefik:v2.0
    restart: always
    container_name: traefik
    ports:
      - "80:80" # <== http
      - "8080:8080" # <== :8080 é onde o painel roda
      - "443:443" # <== https
    command:
    #### Estes são os comandos CLI que configurarão o Traefik e indicarão como ele deve funcionar! ####

      - --api.insecure=true # <== Habilitando API insegura, NÃO RECOMENDADO PARA PRODUÇÃO
      - --api.dashboard=true # <== Habilitando o painel para visualizar serviços, middlewares, roteadores, etc...
      - --api.debug=true # <== Habilitando endpoints adicionais para depuração e perfilamento
      ## Configurações de Log (opções: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
      - --log.level=DEBUG # <== Definindo o nível dos logs do traefik
      ## Configurações do Provedor - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== Habilitando Docker como provedor para o traefik
      - --providers.docker.exposedbydefault=false # <== Não expor cada container ao traefik, expor apenas os habilitados
      - --providers.file.filename=/dynamic.yaml # <== Referenciando um arquivo de configuração dinâmica
      - --providers.docker.network=web # <== Operar na rede Docker chamada web
      ## Configurações dos Pontos de Entrada - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== Definindo um ponto de entrada para a porta :80 chamado web
      - --entrypoints.web-secured.address=:443 # <== Definindo um ponto de entrada para https na porta :443 chamado web-secured
      ## Configurações de Certificado (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== Habilitar TLS-ALPN-01 para gerar e renovar certificados ACME
      - --certificatesresolvers.mytlschallenge.acme.email=private@private.com # <== Definindo e-mail para certificados
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== Definindo arquivo acme para armazenar informações do certificado
    volumes:
      - ./letsencrypt:/letsencrypt # <== Volume para certificados (TLS)
      - /var/run/docker.sock:/var/run/docker.sock # <== Volume para administração do Docker
      - ./dynamic.yaml:/dynamic.yaml # <== Volume para arquivo de configuração dinâmica, **ref: linha 27
    networks:
      - web # <== Colocando o traefik na rede chamada web, para acessar containers nesta rede
    labels:
    #### Labels definem o comportamento e as regras do proxy traefik para este container ####
      - "traefik.enable=true" # <== Habilitar traefik em si mesmo para visualizar o painel e atribuir subdomínio para acessá-lo
      - "traefik.http.routers.api.rule=Host(`monitor.private.com`)" # <== Definindo o domínio para o painel
      - "traefik.http.routers.api.service=api@internal" # <== Habilitando a API como um serviço para acesso


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

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

Discourse app.yml
## este é o template de container Docker all-in-one, standalone do Discourse
##
## Após fazer alterações neste arquivo, você DEVE reconstruir
## /var/discourse/launcher rebuild app
##
## TENHA *MUITO* CUIDADO AO EDITAR!
## ARQUIVOS YAML SÃO SUPER SUPER SENSÍVEIS A ERROS DE ESPAÇAMENTO OU ALINHAMENTO!
## visite http://www.yamllint.com/ para validar este arquivo conforme necessário

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomente estas duas linhas se desejar adicionar Let's Encrypt (https)
  #- "templates/web.ssl.template.yml"
  # "templates/web.letsencrypt.ssl.template.yml"

## quais portas TCP/IP este container deve expor?
## Se você quiser que o Discourse compartilhe uma porta com outro servidor web como Apache ou nginx,
## consulte https://meta.discourse.org/t/17247 para detalhes
expose:
  #- "80:80"   # http
  #- "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Defina db_shared_buffers para no máximo 25% da memória total.
  ## será definido automaticamente pelo bootstrap com base na RAM detectada, ou você pode substituir
  db_shared_buffers: "128MB"

  ## pode melhorar o desempenho de ordenação, mas aumenta o uso de memória por conexão
  #db_work_mem: "40MB"

  ## Qual revisão do Git este container deve usar? (padrão: tests-passed)
  #version: tests-passed

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

  ## Quantas solicitações web simultâneas são suportadas? Depende da memória e dos núcleos da CPU.
  ## será definido automaticamente pelo bootstrap com base nas CPUs detectadas, ou você pode substituir
  UNICORN_WORKERS: 2

  ## TODO: O nome de domínio ao qual esta instância do Discourse responderá
  ## Obrigatório. O Discourse não funcionará com um número IP puro.
  DISCOURSE_HOSTNAME: forum.private.com

  ## Descomente se quiser que o container seja iniciado com o mesmo
  ## hostname (-h option) especificado acima (padrão "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Lista de e-mails separados por vírgula que serão feitos administradores e desenvolvedores
  ## no cadastro inicial, exemplo 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'private@private.com'

  ## TODO: O servidor SMTP usado para validar novas contas e enviar notificações
  ## Endereço SMTP, nome de usuário e senha são obrigatórios
  # AVISO: o caractere '#' na senha do SMTP pode causar problemas!
  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           # (opcional, padrão true)

  ## Se você adicionou o template do Let's Encrypt, descomente abaixo para obter um certificado SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: private@private.com

  ## O endereço http ou https do CDN para esta instância do Discourse (configurado para buscar)
  ## consulte https://meta.discourse.org/t/14857 para detalhes
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## O container Docker é sem estado; todos os dados são armazenados em /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins vão aqui
## consulte https://meta.discourse.org/t/19157 para detalhes
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Quaisquer comandos personalizados para executar após a construção
run:
  - exec: echo "Início dos comandos personalizados"
  ## Se quiser definir o endereço de e-mail 'De' para seu primeiro registro, descomente e altere:
  ## Após receber o primeiro e-mail de cadastro, recomente a linha. Só precisa rodar uma vez.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Fim dos comandos personalizados"

labels:
  app_name:                                                                     discourse

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

   #---SEÇÃO DE ROTEADOR HTTP-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.private.com`)
    #--SEÇÃO HTTP--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---SEÇÃO DE ROTEADOR HTTPS
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.private.com`)
    #--SEÇÃO HTTPS
  traefik.http.routers.discourse_secure.entrypoints:                            web-secured
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--SEÇÃO TLS
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---SEÇÃO DE MIDDLEWARE redirecionar http para https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Obrigado