Traefik 2.0 での Discourse の運用について

みなさん、こんにちは。

新しいサーバーへの移行を行っており、リバースプロキシとして Traefik 2.0 を使用したいと考えています。現在、新しい設定に苦戦しています。app.yml ファイルの下部にセクションを追加しました(出典: https://meta.discourse.org/t/discourse-behind-traefik/84874)。

...

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"

しかし、うまくいかないようです。ルートを開くと Bad Gateway エラーが表示されます。一方、ip_adress:8060 に直接アクセスすると Discourse が開きます。

Traefik 2.0 の使用経験がある方はいますか?

よろしくお願いいたします!

いくつか試した結果、自力で解決できました。

参考のために、私の app.yml を添付します:

...

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Lets Encrypt (https) を追加したい場合は、以下の 2 行のコメントを外してください
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  #- "templates/web.socketed.template.yml" 

## このコンテナが公開すべき TCP/IP ポートはどれですか?
## Discourse を Apache や nginx などの他の Web サーバーとポートを共有させたい場合は、
## 詳細は https://meta.discourse.org/t/17247 を参照してください
#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"

なぜ docker_args を使用する必要があるのでしょうか?GitHub - discourse/discourse_docker: A Docker image for Discourse · GitHub によると、以下のように動作するはずです:

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

現在のコンテナにラベルを追加します。上記は、コンテナを実行する際に --l monitor=true -l app_name=dev_discourse をオプションとして追加します。

さらに、docker_args はどこで説明されていますか?

@Cameron_D
docker_args が正解だとどうやってわかったのですか?

ラベルセクションが期待通りに動作しませんでした。なぜ動作しなくなったのか、あるいはその後修正されたのかは正確にはわかりませんが、設定は変更せずにそのままにしています。なぜなら、現在動作しているからです。

こんにちは、
Traefik の設定を共有していただけませんか?

302 エラーが発生し、自動的に HTTPS にリダイレクトされた後、そこで止まってしまいます。
Traefik のダッシュボードではすべて正常と表示されています。

私の docker-compose.yml はここです
version: "3.7"
    services:
      traefik-reverse-proxy:   
        # 公式の v2.0 Traefik Docker イメージ
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # Traefik に Docker を監視させる
          - --providers.docker          # (デフォルト: true)
          # API/ダッシュボードを有効化 / Docker エンドポイントを Docker の API と通信するように設定
          - --api=true                    # (デフォルト: false)
          # ダッシュボードを有効化
          - --api.dashboard               # (デフォルト: true)
          # Web UI を有効化 / Traefik はデフォルトで API リクエストをポート 8080 で待ち受けます / 名前付きエントリーポイント 'traefik' で API を直接有効化 (デフォルト: false) --> ポート '8080'v= エントリーポイント 'traefik'、--api を上書き
          - --api.insecure=true         # (デフォルト: false) 
          # デバッグとプロファイリング用の追加エンドポイントを有効化
          - --api.debug=true            # (デフォルト: false)
          # ログのデバッグレベルを設定
          - --log.level=DEBUG    
          # アクセスログの書き出し
          - --accesslog=true    
          # コンテナ内の保存場所を定義、ログファイルはコンテナ内に書き出されます。ホストから利用可能にするにはマウントします(volumes セクションを参照)
          - --log.filePath=/var/traefik-container/logs/traefik-log.log
          - --accesslog.filepath=/var/traefik-container/logs/traefik-access.log
          # デフォルトのポート 80 エントリーポイント名を "web" に上書き
          - --entrypoints.web.address=:80
          # ポート 443 のエントリーポイント名を宣言
          - --entrypoints.websecure.address=:443
          #--providers.docker.endpoint=unix:///var/run/docker.sock    
          # Let's Encrypt
          - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true
          - --certificatesresolvers.mytlschallenge.acme.email=my@email.com
          - --certificatesresolvers.mytlschallenge.acme.storage=/var/traefik-container/letsencrypt/acme.json
        ports:
          # HTTP ポート
          - "80:80"
          # HTTPS ポート
          - "443:443"
          # Web UI (--api.insecure=true で有効)
          - "8080:8080"
        volumes:        # 構文 --> ホストの場所:コンテナ内のパス
          # Traefik が Docker イベントを監視できるようにするため
          - /var/run/docker.sock:/var/run/docker.sock
          - /var/traefik/log:/var/traefik-container/logs
          - /var/traefik/letsencrypt:/var/traefik-container/letsencrypt
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=bridge_proxy_traefikv2"
          - "traefik.http.routers.traefikv2.rule=Host(`traefik.mydomain.community`)"
          - "traefik.http.routers.traefikv2.entrypoints=web"
          - "traefik.http.services.traefikv2.loadBalancer.server.port=80"

        networks:
          - traefik
          #- default
          
       # OS 情報と HTTP リクエストを出力する Tiny Go ウェブサーバー
    #  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
私の Discourse app.yml はここです
## これはオールインワン、スタンドアローンの Discourse Docker コンテナテンプレートです
##
## このファイルを編集した後、必ず再構築してください
## /var/discourse/launcher rebuild app
##
## 編集時には *非常に* 注意してください!
## YAML ファイルは空白やアライメントの誤りに非常に敏感です!
## 必要に応じて http://www.yamllint.com/ でこのファイルを検証してください

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Let's Encrypt (https) を追加したい場合は、以下の 2 行のコメントを外してください
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## このコンテナが公開する TCP/IP ポートはどれですか?
## Discourse を Apache や nginx などの他のウェブサーバーとポートを共有したい場合は、
## https://meta.discourse.org/t/17247 を参照してください
expose:
#  - "80:80"   # http
#  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## db_shared_buffers を総メモリの最大 25% に設定します。
  ## ブートストラップ時に検出された RAM に基づいて自動的に設定されますが、上書きすることもできます
  db_shared_buffers: "128MB"

  ## ソートパフォーマンスを向上させることができますが、接続ごとにメモリ使用量が増加します
  #db_work_mem: "40MB"

  ## このコンテナが使用する Git リビジョンはどれですか?(デフォルト: tests-passed)
  #version: tests-passed

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

  ## 同時にサポートされるウェブリクエストの数はいくつですか?メモリと CPU コア数に依存します。
  ## ブートストラップ時に検出された CPU に基づいて自動的に設定されますが、上書きすることもできます
  UNICORN_WORKERS: 2

  ## TODO: この Discourse インスタンスが応答するドメイン名
  ## 必須です。Discourse は IP アドレスのみでは動作しません。
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## 上記で指定したホスト名 (-h オプション) と同じホスト名でコンテナを起動したい場合は、コメントを外してください
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 初期登録時に管理者および開発者として登録されるメールアドレスのカンマ区切りリスト
  ## 例: 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'discourse@myemail.com'

  ## TODO: 新しいアカウントの検証と通知の送信に使用する SMTP メールサーバー
  # SMTP アドレス、ユーザー名、パスワードは必須です
  # 警告: SMTP パスワードに '#' 文字が含まれていると問題が発生する可能性があります!
  DISCOURSE_SMTP_ADDRESS: smtp.zoho.eu
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: discourse@myemail.com
  DISCOURSE_SMTP_PASSWORD: "tempPassword"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (オプション、デフォルト true)

  ## Let's Encrypt テンプレートを追加した場合、以下をコメント外して無料の SSL 証明書を取得してください
  LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## この Discourse インスタンスの http または https CDN アドレス(取得用に設定)
  ## 詳細は https://meta.discourse.org/t/14857 を参照してください
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
## Docker コンテナはステートレスです。すべてのデータは /shared に保存されます
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## プラグインはここに追加してください
## 詳細は https://meta.discourse.org/t/19157 を参照してください
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## ビルド後に実行する任意のカスタムコマンド
run:
  - exec: echo "カスタムコマンドの開始"
  ## 最初の登録の 'From' メールアドレスを設定したい場合は、コメントを外して変更してください
  ## 最初の登録メールが届いた後、再度コメントアウトしてください。一度だけ実行すれば十分です
  - exec: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "カスタムコマンドの終了"

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
直接タグ付けして申し訳ありませんが、Traefik の背後で Discourse を運用していることが文書化されているのは、どうやらあなた方だけのようです。
Traefik がすべてを処理してくれるという約束にもかかわらず、設定は思ったほど簡単ではないようです。
今のところ、私は成功していません:

動作している URL:
動作しない URL:

より良いトラブルシューティングができるよう、Discourse と Traefik の完全な設定を共有していただければ大変感謝いたします。

私の Traefik 設定は、この投稿の最後にあります:Endless 502 / forwarding when calling dashboard via subdomain #6123 - #9 by PackElend - Traefik v2 - Traefik Labs Community Forum

モバイルのみでの利用のため、設定はこちらでご確認ください: traefik - SeAT Discourse Documentation

ご注意: 動作確認は Traefik の v1.6 および v1.7 のみです。v2 での動作は不明です。

これにより、複数のユーザーが当プラグイン、Discourse、Traefik を利用できるようになりました。

なお、このスレッドの投稿は一つも読んでいません。ping への回答のみです。

どうもありがとう :slight_smile: :partying_face:

v1 から v2 への移行を試みてみます。

すでに大まかな構想は浮かびましたが、整理するのに数時間必要そうです。

SSL と Let’s Encrypt に関するテンプレートはコメントアウトされているため、テンプレートセクションは以下のようになっているはずです。

    templates:
          - "templates/postgres.template.yml"
          - "templates/redis.template.yml"
          - "templates/web.template.yml"
          - "templates/web.ratelimited.template.yml"
        ## Let's Encrypt (https) を追加したい場合は、以下の 2 行のコメントを外してください
          #- "templates/web.ssl.template.yml"
          #- "templates/web.letsencrypt.ssl.template.yml"

はい、前方にプロキシを有効にする予定があるのに、なぜ Discourse コンテナに SSL 証明書的管理を任せる必要があるのでしょうか?

完了次第、解決策を投稿してください。

Run other websites on the same machine as Discourse - #301 をご覧ください。

ドキュメントにもテンプレートセクションを追加することをお勧めします。私が app.yml を取得するために最初にスタンドアロンでインストールした際、私のインストールではコメントアウトされていなかったことに気づきました。最初はそれらをコメントアウトするのを忘れました。他の人が同じ問題に直面しないようにするためです。

もちろん

Traefikの静的設定が表示されていないようですが、いかがでしょうか?

皆さん、朗報ですhttp://forum.fairbnb.community/ にアクセスできます。

http で提供するために app.yml を最小限に変更した設定です。週末に https について詳しく調べます。

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## Lets Encrypt (https) を追加したい場合は、この 2 行のコメントを外してください
    #- "templates/web.ssl.template.yml"
    #- "templates/web.letsencrypt.ssl.template.yml"  

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

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

SSL については、Traefik と Let’s Encrypt を設定するだけでよく、Discourse の SSL 機能を使う必要はありません。

Traefik がすべてのコンテナの暗号化を管理します。

現在、私は Traefik 1.6 を使用しているため、Traefik v2 でそれを有効にする方法はまだわかりません。

はい、Run other websites on the same machine as Discourse をご覧ください。ただし、クライアントが HTTPS を介してプロキシと通信する際に、Discourse が特定のヘッダー情報を期待しているようです。

少しだけ読み進めました。これを一般のビジネスパーソンにもわかりやすい表現に翻訳してみます。

はい、Redirecting... も参照してください。最初は最初から HTTPS を設定し、証明書の作成も成功しましたが、それだけです。その後、得た知識に合わせて設定を調整する必要があります。

つまり、あなたのフォーラムには HTTPS でアクセスしているのですね?
Traefik と Discourse の設定を共有していただけませんか?情報が共有されるほど、週末に私が対応しやすくなります。
v1 から v2 への移行ガイドは Redirecting... にありますが、週末にここで詳しく説明するようにします。

OK、これが私の traefik.toml ですが、新しいバージョン v2 では無効です

defaultEntryPoints = ["http", "https"]

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

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

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

Discourse 設定の一部

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

expose:
  - "80"   # http ------ コンテナポートを公開するだけ
  - "443" # https ------ 外部ホストポートを公開する必要はありません

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

この設定では、Traefik がポート 80(HTTP)からのすべてのリクエストをポート 443(HTTPS)にリダイレクトします。
エラーを回避するために、Discourse の管理パネルで FORCE HTTPS を有効にしてください。

@pfaffman、別のトピックであなたの返信を引用しても通知が機能するかどうかはわかりませんので、タグ付けしました。

したがって、あなたの設定は上記のものと似ていますが、

環境変数を使用しています(このアプローチは https://stackoverflow.com/questions/52804610/how-do-you-set-environmental-variables-for-traefik および https://blog.raveland.org/post/traefik_compose で参照されています)。

なので、https が動作しています :partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
また、その仕組みがおおむね理解できたと思います :slight_smile:. 今後数日中にまとめて書こうと思います

私の設定

discourse app.yml の抜粋

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Lets Encrypt (https) を追加したい場合は、以下の 2 行のコメントを外してください
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## このコンテナが公開すべき TCP/IP ポートはどれですか?
## Discourse を Apache や nginx などの他の Web サーバーとポートを共有したい場合は、
## https://meta.discourse.org/t/17247 を参照してください
expose:
  #- "80:80"   # http
  #- "443:443" # https
  #- "80"      # http
  #- "443"     # https
  #- "40080:80"
  #- "40443:443"

labels:
  app_name:                                                                     discourse

  #----Traefik ラベル------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       bridge_proxy_traefikv2

   #---HTTP ルーターセクション-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.fairbnb.community`)
    #--HTTP セクション--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  #traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---HTTPS ルーターセクション
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.fairbnb.community`)
    #--HTTPS セクション
  traefik.http.routers.discourse_secure.entrypoints:                            websecure
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--TLS セクション
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---ミドルウェアセクション HTTP を HTTPS にリダイレクト
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

Traefik 静的設定

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

api:
   debug: true

providers:
  docker:
    exposedByDefault: false
    network: bridge_proxy_traefikv2

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

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

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

こんにちは、

Discourse を Traefik と連携させるためのガイドとして、この投稿を利用しました。私はすでに別の Web アプリで Traefik を動作させています。

forum.private.com にアクセスすると、「404 ページが見つかりません」というエラーが表示されます。

何らかの動作はしているようです。なぜなら、Traefik のダッシュボードの「サービス」タブを見ると、discourse@dockerdiscourse_secure@docker が表示されているからです。

しかし、「ルーター」タブには Discourse に関する項目は何もありません。

私が app.yml に加えた変更は以下の通りで、主に上記の投稿を参考にしています。下部の Docker 引数に公開ポートを追加したところ、上記のサービスが公開されたように見えました。ご助力いただければ幸いです!

Traefik docker-compose
version: "3.3"

services:
  ################################################
  ####        Traefik Proxy Setup           #####
  ###############################################
  traefik:
    image: traefik:v2.0
    restart: always
    container_name: traefik
    ports:
      - "80:80" # <== http
      - "8080:8080" # <== :8080 はダッシュボードが動作する場所
      - "443:443" # <== https
    command:
    #### これらは Traefik を設定し、動作方法を指示する CLI コマンドです!####

      - --api.insecure=true # <== 不安全な API を有効化(本番環境では非推奨)
      - --api.dashboard=true # <== サービス、ミドルウェア、ルーターなどを表示するためのダッシュボードを有効化
      - --api.debug=true # <== デバッグとプロファイリング用の追加エンドポイントを有効化
      ## ログ設定(オプション: ERROR, DEBUG, PANIC, FATAL, WARN, INFO)- https://docs.traefik.io/observability/logs/ ##
      - --log.level=DEBUG # <== Traefik のログレベルを設定
      ## プロバイダー設定 - https://docs.traefik.io/providers/docker/#provider-configuration ##
      - --providers.docker=true # <== Docker を Traefik のプロバイダーとして有効化
      - --providers.docker.exposedbydefault=false # <== すべてのコンテナを Traefik に公開せず、有効化されたもののみを公開
      - --providers.file.filename=/dynamic.yaml # <== 動的設定ファイルを参照
      - --providers.docker.network=web # <== "web" という名前の Docker ネットワークで動作
      ## エントリポイント設定 - https://docs.traefik.io/routing/entrypoints/#configuration ##
      - --entrypoints.web.address=:80 # <== ポート :80 用のエントリポイント "web" を定義
      - --entrypoints.web-secured.address=:443 # <== ポート :443 用の HTTPS エントリポイント "web-secured" を定義
      ## 証明書設定(Let's Encrypt)- https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== TLS-ALPN-01 を有効化して ACME 証明書を生成・更新
      - --certificatesresolvers.mytlschallenge.acme.email=private@private.com # <== 証明書用のメールを設定
      - --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== 証明書情報を保存する ACME ファイルを定義
    volumes:
      - ./letsencrypt:/letsencrypt # <== 証明書(TLS)用のボリューム
      - /var/run/docker.sock:/var/run/docker.sock # <== Docker 管理用のボリューム
      - ./dynamic.yaml:/dynamic.yaml # <== 動的設定ファイル用のボリューム、**参照: 行 27
    networks:
      - web # <== "web" という名前のネットワーク上に Traefik を配置し、このネットワーク上のコンテナにアクセス可能にする
    labels:
    #### ラベルはこのコンテナの Traefik プロキシの動作とルールを定義します ####
      - "traefik.enable=true" # <== 自身で Traefik を有効化し、ダッシュボードを表示し、サブドメインを割り当てて表示可能にする
      - "traefik.http.routers.api.rule=Host(`monitor.private.com`)" # <== ダッシュボード用のドメインを設定
      - "traefik.http.routers.api.service=api@internal" # <== API をアクセス可能なサービスとして有効化


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

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

Discourse app.yml
## これはオールインワンのスタンドアロン Discourse Docker コンテナテンプレートです
##
## このファイルを変更した後は、必ず再構築が必要です
## /var/discourse/launcher rebuild app
##
## 編集時は非常に注意してください!
## YAML ファイルは空白やアライメントのミスに非常に敏感です!
## 必要に応じて http://www.yamllint.com/ にアクセスしてこのファイルを検証してください

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Lets Encrypt (https) を追加する場合は、以下の 2 行のコメントを外してください
  #- "templates/web.ssl.template.yml"
  # "templates/web.letsencrypt.ssl.template.yml"

## このコンテナが公開する TCP/IP ポートはどれですか?
## Discourse を Apache や nginx などの他の Web サーバーとポートを共有させたい場合は、
## https://meta.discourse.org/t/17247 を参照してください
expose:
  #- "80:80"   # http
  #- "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## db_shared_buffers を総メモリの最大 25% に設定します。
  ## 検出された RAM に基づいてブートストラップで自動的に設定されますが、上書きすることもできます
  db_shared_buffers: "128MB"

  ## ソートパフォーマンスを向上させることができますが、接続ごとのメモリ使用量が増加します
  #db_work_mem: "40MB"

  ## このコンテナで使用する Git リビジョンはどれですか?(デフォルト: tests-passed)
  #version: tests-passed

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

  ## 同時にサポートされる Web リクエスト数は?メモリと CPU コア数に依存します。
  ## 検出された CPU に基づいてブートストラップで自動的に設定されますが、上書きすることもできます
  UNICORN_WORKERS: 2

  ## TODO: この Discourse インスタンスが応答するドメイン名
  ## 必須です。Discourse は IP アドレスのみでは動作しません。
  DISCOURSE_HOSTNAME: forum.private.com

  ## 上記で指定されたホスト名(-h オプション)と同じホスト名でコンテナを起動したい場合は、
  ## 以下の行のコメントを外してください(デフォルト: "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 初期登録時に管理者および開発者にされるメールアドレスのカンマ区切りリスト
  ## 例: 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'private@private.com'

  ## TODO: 新しいアカウントの検証と通知の送信に使用する SMTP メールサーバー
  # SMTP アドレス、ユーザー名、パスワードは必須です
  # 警告:SMTP パスワードに含まれる '#' 文字は問題を引き起こす可能性があります!
  DISCOURSE_SMTP_ADDRESS: in-v3.mailjet.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: redacted
  DISCOURSE_SMTP_PASSWORD: "redacted"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (オプション、デフォルトは true)

  ## Lets Encrypt テンプレートを追加した場合、以下の行のコメントを外して無料の SSL 証明書を取得してください
  LETSENCRYPT_ACCOUNT_EMAIL: private@private.com

  ## この Discourse インスタンスの HTTP または HTTPS CDN アドレス(プルするように設定)
  ## 詳細は https://meta.discourse.org/t/14857 を参照してください
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## Docker コンテナはステートレスです。すべてのデータは /shared に保存されます
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## プラグインはここにあります
## 詳細は https://meta.discourse.org/t/19157 を参照してください
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## ビルド後に実行する任意のカスタムコマンド
run:
  - exec: echo "カスタムコマンドの開始"
  ## 最初の登録用の 'From' メールアドレスを設定したい場合は、以下の行のコメントを外して変更してください:
  ## 最初の登録メールを受信した後、再度コメントアウトしてください。一度だけ実行すれば十分です。
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "カスタムコマンドの終了"

labels:
  app_name:                                                                     discourse

  #----Traefik ラベル------------------------
  traefik.enable:                                                               true
  traefik.docker.network:                                                       web

   #---HTTP ルーターセクション-------------------
  traefik.http.routers.discourse.rule:                                          Host(`forum.private.com`)
    #--HTTP セクション--------------------------
  traefik.http.routers.discourse.entrypoints:                                   web
  traefik.http.routers.discourse.middlewares:                                   discourse_redirect2https         
  traefik.http.services.discourse.loadbalancer.server.port:                     80  

   #---HTTPS ルーターセクション
  traefik.http.routers.discourse_secure.rule:                                   Host(`forum.private.com`)
    #--HTTPS セクション
  traefik.http.routers.discourse_secure.entrypoints:                            web-secured
  traefik.http.services.discourse_secure.loadbalancer.server.port:              80
    #--TLS セクション
  traefik.http.routers.discourse_secure.tls.certresolver:                       tlsChallenge_letsencrypt

   #---ミドルウェアセクション HTTP を HTTPS にリダイレクト
  traefik.http.middlewares.discourse_redirect2https.redirectscheme.scheme:      https

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

ありがとうございます