Discusión con Traefik 2.0

Hola a todos,

Estoy migrando a un nuevo servidor y quiero usar Traefik 2.0 como proxy inverso. Actualmente estoy teniendo problemas con la nueva configuración. He añadido una sección al final del archivo app.yml. (Fuente: 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"

Esto no parece funcionar. Cuando abro la ruta, obtengo un error de Bad Gateway. Sin embargo, si voy directamente a ip_adress:8060, Discourse se abre correctamente.

¿Alguien tiene experiencia con Traefik 2.0?

¡Gracias!

Después de varios intentos, pude resolverlo por mi cuenta.

Para mayor referencia, adjunto mi app.yml:

...

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomenta estas dos líneas si deseas agregar Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  #- "templates/web.socketed.template.yml" 

## ¿Qué puertos TCP/IP debe exponer este contenedor?
## Si deseas que Discourse comparta un puerto con otro servidor web como Apache o nginx,
## consulta https://meta.discourse.org/t/17247 para obtener detalles
#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 qué es necesario usar docker_args? Según GitHub - discourse/discourse_docker: A Docker image for Discourse · GitHub, debería funcionar así:

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

Agrega etiquetas al contenedor actual. Lo anterior añadirá --l monitor=true -l app_name=dev_discourse a las opciones al ejecutar el contenedor.

Además, ¿dónde se explica docker_args?

@Cameron_D
¿Cómo descubriste que docker_args es la forma correcta?

Simplemente no pude hacer que la sección de etiquetas funcionara como esperaba. No estoy seguro exactamente de por qué dejó de funcionar, ni de si se ha solucionado desde entonces, porque he dejado mi configuración tal cual está ya que funciona.

Hola,
¿puedes compartir tu configuración de Traefik?

Termino con un 302, redirige automáticamente a HTTPS y luego se queda colgado…
El panel de control de Traefik dice que todo está bien.

mi docker-compose.yml está aquí
version: "3.7"
    services:
      traefik-reverse-proxy:   
        # La imagen oficial de Docker de Traefik v2.0
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # Indicar a Traefik que escuche a Docker 
          - --providers.docker          # (Por defecto: true)
          # Habilitar API/panel de control / (configurar el endpoint de Docker para comunicarse con la API de Docker)
          - --api=true                    # (Por defecto: false)
          # Activar el panel de control. 
          - --api.dashboard               # (Por defecto: true)
          # Habilitar la interfaz web / Traefik escuchará por defecto en el puerto 8080 para solicitudes de la API. / Activar la API directamente en el entryPoint llamado traefik. (Por defecto: false) --> puerto '8080'v= entryPoint 'traefik', sobrescribe --api
          - --api.insecure=true         # (Por defecto: false) 
          # Habilitar endpoints adicionales para depuración y perfilado. 
          - --api.debug=true            # (Por defecto: false)
          # establecer el nivel de depuración del registro
          - --log.level=DEBUG    
          # escribir el accesslog
          - --accesslog=true    
          # definir la ubicación de almacenamiento dentro del contenedor, el archivo de registro se escribe dentro del contenedor. Para hacerlo disponible en el host, se monta, ver sección volumes
          - --log.filePath=/var/traefik-container/logs/traefik-log.log
          - --accesslog.filepath=/var/traefik-container/logs/traefik-access.log
          # sobrescribir el nombre del entrypoint del puerto 80 por defecto por "web"
          - --entrypoints.web.address=:80
          # declarar el nombre del entrypoint para el puerto 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:
          # El puerto HTTP
          - "80:80"
          # El puerto HTTPS
          - "443:443"
          # La interfaz web (habilitada por --api.insecure=true)
          - "8080:8080"
        volumes:        # sintaxis --> ubicación-host:ruta-en-contenedor
          # Para que Traefik pueda escuchar los eventos de 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
          
       #Pequeño servidor web en Go que imprime información del SO y la solicitud HTTP en la salida
    #  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
mi app.yml de Discourse está aquí
## esta es la plantilla de contenedor Docker todo-en-uno, independiente de Discourse
##
## Después de realizar cambios en este archivo, DEBES reconstruir
## /var/discourse/launcher rebuild app
##
## ¡TEN *MUCHO* CUIDADO AL EDITAR!
## ¡LOS ARCHIVOS YAML SON SUPER SENSIBLES A ERRORES EN ESPACIOS EN BLANCO O ALINEACIÓN!
## visita http://www.yamllint.com/ para validar este archivo según sea necesario

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomenta estas dos líneas si deseas agregar Let's Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## ¿Qué puertos TCP/IP debe exponer este contenedor?
## Si deseas que Discourse comparta un puerto con otro servidor web como Apache o nginx,
## consulta https://meta.discourse.org/t/17247 para más detalles
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Establece db_shared_buffers a un máximo del 25% de la memoria total.
  ## se establecerá automáticamente por bootstrap según la RAM detectada, o puedes sobrescribirlo
  db_shared_buffers: "128MB"

  ## puede mejorar el rendimiento de ordenación, pero añade uso de memoria por conexión
  #db_work_mem: "40MB"

  ## ¿Qué revisión de Git debe usar este contenedor? (por defecto: 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

  ## ¿Cuántas solicitudes web simultáneas se admiten? Depende de la memoria y los núcleos de CPU.
  ## se establecerá automáticamente por bootstrap según los CPUs detectados, o puedes sobrescribirlo
  UNICORN_WORKERS: 2

  ## TODO: El nombre de dominio al que responderá esta instancia de Discourse
  ## Requerido. Discourse no funcionará con una dirección IP desnuda.
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## Descomenta si deseas que el contenedor se inicie con el mismo
  ## nombre de host (opción -h) que se especificó anteriormente (por defecto "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Lista de correos electrónicos separados por comas que serán administradores y desarrolladores
  ## en el registro inicial, ejemplo 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'discourse@myemail.com'

  ## TODO: El servidor de correo SMTP utilizado para validar nuevas cuentas y enviar notificaciones
  # DIRECCIÓN SMTP, nombre de usuario y contraseña son obligatorios
  # ADVERTENCIA: el carácter '#' en la contraseña SMTP puede 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, por defecto true)

  ## Si agregaste la plantilla de Let's Encrypt, descomenta abajo para obtener un certificado SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## La dirección http o https de la CDN para esta instancia de Discourse (configurada para extraer)
  ## consulta https://meta.discourse.org/t/14857 para más detalles
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
## El contenedor Docker es sin estado; todos los datos se almacenan en /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Los plugins van aquí
## consulta https://meta.discourse.org/t/19157 para más detalles
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Cualquier comando personalizado para ejecutar después de la construcción
run:
  - exec: echo "Inicio de comandos personalizados"
  ## Si deseas establecer la dirección de correo electrónico 'From' para tu primer registro, descomenta y cambia:
  ## Después de recibir el primer correo de registro, vuelve a comentar la línea. Solo necesita ejecutarse una vez.
  - exec: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "Fin de 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
Disculpad por etiquetaros directamente, pero parece que sois los únicos usuarios documentados que ejecutáis Discourse detrás de Traefik.
A pesar de la promesa de que Traefik se encargará de todo, parece que no es tan sencillo de configurar.
Hasta ahora, no he tenido éxito:

URLs que funcionan:
URL que no funciona:

Agradecería mucho que pudierais compartir la configuración completa de Discourse y Traefik, para poder solucionar el problema de manera más efectiva.

Mis configuraciones de Traefik al final de este post: Endless 502 / forwarding when calling dashboard via subdomain #6123 - #9 by PackElend - Traefik v2 - Traefik Labs Community Forum

Como solo estoy en mi móvil, por favor revisa mi configuración aquí: traefik - SeAT Discourse Documentation

Nota: solo lo tuve funcionando con las versiones 1.6 y 1.7 de Traefik. No sé si funcionará con la v2.

Con eso, varios usuarios pudieron usar mi plugin, Discourse y Traefik.

Nota: no he leído ni un solo mensaje en este hilo, solo respondo al aviso.

¡Muchas gracias! :slight_smile: :partying_face:

Voy a intentar adaptarlo de la v1 a la v2.

Ya tengo una idea al respecto, necesito algunas horas para pensarlo bien.

Asumo que las plantillas para SSL y Let’s Encrypt están comentadas, de modo que la sección de plantillas se ve así:

    templates:
          - "templates/postgres.template.yml"
          - "templates/redis.template.yml"
          - "templates/web.template.yml"
          - "templates/web.ratelimited.template.yml"
        ## Descomenta estas dos líneas si deseas agregar Let's Encrypt (https)
          #- "templates/web.ssl.template.yml"
          #- "templates/web.letsencrypt.ssl.template.yml"

Sí, ¿por qué querrías que el contenedor de Discourse gestione tus certificados SSL si vas a habilitar un proxy delante?

Por favor, publica tu solución tan pronto como la termines.

En Run other websites on the same machine as Discourse - #301 ver:

Sugeriría agregar también la sección de plantillas en la documentación. Noté que no estaban comentadas en mi instalación, ya que primero hice una instalación independiente para obtener el app.yml. Al principio, olvidé comentarlas. Esto podría evitar que otros tengan el mismo problema.

Por supuesto.

No muestra la configuración estática de Traefik, ¿verdad?

Buenas noticias a todos ! http://forum.fairbnb.community/ es accesible.

Esta es la configuración con los mínimos cambios en app.yml para que se sirva mediante http; me adentraré en https durante el fin de semana.

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## Descomenta estas dos líneas si deseas agregar 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, simplemente configura Traefik + Let’s Encrypt; no necesitas usar el SSL de Discourse.

Traefik gestionará el cifrado en todos tus contenedores.

Actualmente estoy usando Traefik 1.6, así que aún no sé cómo habilitarlo en Traefik v2.

sí, ver Run other websites on the same machine as Discourse, pero parece que Discourse espera cierta información de encabezado cuando el cliente se comunica con el proxy a través de HTTPS.

Lo he leído brevemente. Intentaré traducirlo a un texto comprensible para el usuario promedio de horario laboral.

sí, ver también en Redirecting.... Al principio, comencé directamente con HTTPS y la creación del certificado fue exitosa, pero eso es todo. Ahora debo alinearlo con el conocimiento que he adquirido desde entonces.

Entonces, ¿usas HTTPS para acceder a tu foro, verdad?
¿Puedes compartir la configuración de Traefik y Discourse? Cuanto más se comparta, más fácil me será el fin de semana.
La guía de migración de v1 a v2 está en Redirecting..., pero intentaré explicarlo aquí el fin de semana.

OK, este es mi traefik.toml, no válido para la nueva versión v2

defaultEntryPoints = ["http", "https"]

[web]
address = ":8080"
  [web.auth.basic]
  users = ["tuusuario:tucontraseña"]

[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 de la configuración de Discourse

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

expose:
  - "80"   # http ------ solo expone los puertos del contenedor 
  - "443" # https ------ no necesitas exponer el puerto del host externo

labels:
  traefik.port: '80'
  traefik.backend: 'miconnombredecontenedor'
  traefik.frontend.rule: 'Host:www.mihost.com'
  traefik.docker.network: 'mirede'
docker_args:
  - "--network=mirede"

con esta configuración, traefik redirige todas las solicitudes del puerto 80 “http” al puerto 443 “https”,
habilita FORZAR HTTPS en el panel de administración de Discourse para evitar errores.

@pfaffman, no sé si las notificaciones siguen funcionando si cito tu respuesta en otro tema, así que te etiqueto.

Tu configuración parece la de arriba, pero

y usando variables de entorno (este enfoque se referencia en https://stackoverflow.com/questions/52804610/how-do-you-set-environmental-variables-for-traefik y https://blog.raveland.org/post/traefik_compose)

así que https funciona :partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
y creo que entendí cómo funciona todo eso :slight_smile:. Intentaré escribirlo en los próximos días

mi configuración

extracto de app.yml de discourse

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomenta estas dos líneas si deseas agregar Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## ¿qué puertos TCP/IP debe exponer este contenedor?
## Si deseas que Discourse comparta un puerto con otro servidor web como Apache o nginx,
## consulta https://meta.discourse.org/t/17247 para obtener detalles
expose:
  #- "80:80"   # http
  #- "443:443" # https
  #- "80"      # http
  #- "443"     # https
  #- "40080:80"
  #- "40443:443"

labels:
  app_name:                                                                     discourse

  #----Etiquetas de Traefik------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       bridge_proxy_traefikv2

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

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

   #---SECCIÓN DE MIDDLEWARE redirigir http a https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Configuración estática de 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: {}

Saludos,

Utilicé esta publicación como guía para configurar Discourse para que funcione con Traefik. Ya tengo Traefik funcionando con otra aplicación web.

Cuando visito forum.private.com, obtengo un error de “404 página no encontrada”.

Parece que algo está funcionando, porque en la pestaña de servicios del panel de control de Traefik, puedo ver discourse@docker y discourse_secure@docker.

Sin embargo, no hay nada relacionado con Discourse en la pestaña de routers.

Los cambios que he realizado en app.yml se encuentran a continuación, basados en gran medida en la publicación enlazada anteriormente. Agregué un puerto expuesto en los argumentos de Docker al final, lo cual pareció habilitar los servicios mencionados anteriormente. ¡Agradecería cualquier ayuda!

Traefik docker-compose
version: "3.3"

services:
  ################################################
  ####        Configuración del Proxy Traefik           #####
  ###############################################
  traefik:
    image: traefik:v2.0
    restart: always
    container_name: traefik
    ports:
      - "80:80" # <== http
      - "8080:8080" # <== :8080 es donde se ejecuta el panel de control
      - "443:443" # <== https
    command:
    #### Estos son los comandos CLI que configurarán Traefik y le indicarán cómo funcionar! ####

      - --api.insecure=true # <== Habilitar API insegura, NO RECOMENDADO PARA PRODUCCIÓN
      - --api.dashboard=true # <== Habilitar el panel de control para ver servicios, middlewares, routers, etc...
      - --api.debug=true # <== Habilitar endpoints adicionales para depuración y perfiles
      ## Configuración de registros (opciones: ERROR, DEBUG, PANIC, FATAL, WARN, INFO) - https://docs.traefik.io/observability/logs/ ##
      - --log.level=DEBUG # <== Establecer el nivel de los registros de Traefik
      ## Configuración de proveedores - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== Habilitar Docker como proveedor para Traefik
      - --providers.docker.exposedbydefault=false # <== No exponer cada contenedor a Traefik, solo exponer los habilitados
      - --providers.file.filename=/dynamic.yaml # <== Referenciar un archivo de configuración dinámica
      - --providers.docker.network=web # <== Operar en la red Docker llamada web
      ## Configuración de puntos de entrada - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== Definir un punto de entrada para el puerto :80 llamado web
      - --entrypoints.web-secured.address=:443 # <== Definir un punto de entrada para HTTPS en el puerto :443 llamado web-secured
      ## Configuración de certificados (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== Habilitar TLS-ALPN-01 para generar y renovar certificados ACME
      - --certificatesresolvers.mytlschallenge.acme.email=private@private.com # <== Establecer el correo electrónico para los certificados
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== Definir el archivo ACME para almacenar información del certificado
    volumes:
      - ./letsencrypt:/letsencrypt # <== Volumen para certificados (TLS)
      - /var/run/docker.sock:/var/run/docker.sock # <== Volumen para administración de Docker
      - ./dynamic.yaml:/dynamic.yaml # <== Volumen para archivo de configuración dinámica, **ref: línea 27
    networks:
      - web # <== Colocar Traefik en la red llamada web, para acceder a contenedores en esta red
    labels:
    #### Las etiquetas definen el comportamiento y las reglas del proxy Traefik para este contenedor ####
      - "traefik.enable=true" # <== Habilitar Traefik en sí mismo para ver el panel de control y asignar un subdominio para verlo
      - "traefik.http.routers.api.rule=Host(`monitor.private.com`)" # <== Establecer el dominio para el panel de control
      - "traefik.http.routers.api.service=api@internal" # <== Habilitar la API como un servicio para acceder


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

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

Discourse app.yml
## Esta es la plantilla de contenedor Docker todo en uno y autónomo de Discourse
##
## Después de realizar cambios en este archivo, DEBES reconstruir
## /var/discourse/launcher rebuild app
##
## TEN *MUCHO* CUIDADO AL EDITAR!
## LOS ARCHIVOS YAML SON SUPER SENSIBLES A ERRORES EN ESPACIOS EN BLANCO O ALINEACIÓN!
## visita http://www.yamllint.com/ para validar este archivo según sea necesario

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Descomenta estas dos líneas si deseas agregar Let's Encrypt (https)
  #- "templates/web.ssl.template.yml"
  # "templates/web.letsencrypt.ssl.template.yml"

## ¿Qué puertos TCP/IP debe exponer este contenedor?
## Si deseas que Discourse comparta un puerto con otro servidor web como Apache o nginx,
## consulta https://meta.discourse.org/t/17247 para obtener detalles
expose:
  #- "80:80"   # http
  #- "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Establece db_shared_buffers a un máximo del 25% de la memoria total.
  ## se establecerá automáticamente durante el arranque según la RAM detectada, o puedes sobrescribirlo
  db_shared_buffers: "128MB"

  ## puede mejorar el rendimiento de ordenación, pero aumenta el uso de memoria por conexión
  #db_work_mem: "40MB"

  ## ¿Qué revisión de Git debe usar este contenedor? (predeterminado: tests-passed)
  #version: tests-passed

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

  ## ¿Cuántas solicitudes web simultáneas son compatibles? Depende de la memoria y los núcleos de CPU.
  ## se establecerá automáticamente durante el arranque según los CPUs detectados, o puedes sobrescribirlo
  UNICORN_WORKERS: 2

  ## TODO: El nombre de dominio al que responderá esta instancia de Discourse
  ## Requerido. Discourse no funcionará con una dirección IP desnuda.
  DISCOURSE_HOSTNAME: forum.private.com

  ## Descomenta si deseas que el contenedor se inicie con el mismo
  ## nombre de host (opción -h) que se especificó anteriormente (predeterminado "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: Lista de correos electrónicos separados por comas que serán administradores y desarrolladores
  ## en el registro inicial, ejemplo 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'private@private.com'

  ## TODO: El servidor de correo SMTP utilizado para validar nuevas cuentas y enviar notificaciones
  ## SE REQUIEREN DIRECCIÓN, nombre de usuario y contraseña de SMTP
  # ADVERTENCIA: el carácter '#' en la contraseña de SMTP puede 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, predeterminado true)

  ## Si agregaste la plantilla de Let's Encrypt, descomenta a continuación para obtener un certificado SSL gratuito
  LETSENCRYPT_ACCOUNT_EMAIL: private@private.com

  ## La dirección CDN http o https para esta instancia de Discourse (configurada para extraer)
  ## consulta https://meta.discourse.org/t/14857 para obtener detalles
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## El contenedor Docker es sin estado; todos los datos se almacenan en /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Los plugins van aquí
## consulta https://meta.discourse.org/t/19157 para obtener detalles
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Cualquier comando personalizado para ejecutar después de la construcción
run:
  - exec: echo "Comienzo de comandos personalizados"
  ## Si deseas establecer la dirección de correo electrónico 'De' para tu primer registro, descomenta y cambia:
  ## Después de obtener el primer correo electrónico de registro, vuelve a comentar la línea. Solo necesita ejecutarse una vez.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "Fin de comandos personalizados"

labels:
  app_name:                                                                     discourse

  #----Etiquetas de Traefik------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       web

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

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

   #---SECCIÓN DE MIDDLEWARE redirigir http a https
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Gracias