Traefik 2.0와 Discourse 설정

안녕하세요,

새 서버로 이전 중이며 Traefik 2.0을 리버스 프록시로 사용하려고 합니다. 현재 새로운 구성 설정 때문에 어려움을 겪고 있습니다. app.yml 파일 하단에 섹션을 추가했습니다. (출처: 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"

이것이 작동하지 않는 것 같습니다. 해당 경로를 열면 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)를 추가하려면 다음 두 줄의 주석을 해제하세요
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
  #- "templates/web.socketed.template.yml" 

## 이 컨테이너가 노출할 TCP/IP 포트는?
## Apache나 nginx 같은 다른 웹서버와 포트를 공유하려면
## 자세한 내용은 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 도커 이미지
        image: traefik:latest #traefik:v2.0
        container_name: "traefik"       
        command:
          # Traefik이 도커를 경청하도록 지시
          - --providers.docker          # (기본값: true)
          # api/대시보드 활성화 / (도커 API와 통신하기 위해 도커 엔드포인트 설정)
          - --api=true                    # (기본값: false)
          # 대시보드 활성화. 
          - --api.dashboard               # (기본값: true)
          # 웹 UI 활성화 / Traefik은 기본적으로 API 요청을 위해 포트 8080에서 경청합니다. / traefik이라는 이름의 entryPoint에서 API를 직접 활성화합니다. (기본값: false) --> 포트 '8080'v= entryPoint 'traefik', --api를 재정의합니다
          - --api.insecure=true         # (기본값: false) 
          # 디버깅 및 프로파일링을 위한 추가 엔드포인트 활성화. 
          - --api.debug=true            # (기본값: false)
          # 로그의 디버그 수준 설정
          - --log.level=DEBUG    
          # 액세스 로그 기록
          - --accesslog=true    
          # 컨테이너 내부의 저장 위치 정의, 로그 파일은 컨테이너 내부에 기록됩니다. 호스트에서 사용할 수 있도록 하려면 볼륨 섹션을 참조하여 마운트해야 합니다.
          - --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"
          # 웹 UI (--api.insecure=true로 활성화됨)
          - "8080:8080"
        volumes:        # 구문 --> 호스트-위치:컨테이너-내-경로
          # Traefik이 도커 이벤트를 경청할 수 있도록
          - /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 요청을 출력에 표시하는 작은 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 도커 컨테이너 템플릿입니다
##
## 이 파일에 변경 사항을 적용한 후에는 반드시 재빌드해야 합니다
## /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)를 추가하려면 다음 두 줄의 주석을 해제하세요
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## 이 컨테이너는 어떤 TCP/IP 포트를 노출해야 합니까?
## Apache나 nginx 같은 다른 웹 서버와 Discourse가 포트를 공유하려면
## 자세한 내용은 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에 따라 bootstrap이 자동으로 설정하거나, 직접 재정의할 수 있습니다.
  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에 따라 bootstrap이 자동으로 설정하거나, 직접 재정의할 수 있습니다.
  UNICORN_WORKERS: 2

  ## TODO: 이 Discourse 인스턴스가 응답할 도메인 이름
  ## 필수. Discourse는 IP 주소만으로는 작동하지 않습니다.
  DISCOURSE_HOSTNAME: forum.fairbnb.community

  ## 컨테이너가 위에서 지정된 동일한 호스트 이름(-h 옵션)으로 시작되도록 하려면
  ## 아래 주석을 해제하세요 (기본값 "$hostname-$config")
  #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
  
## 도커 컨테이너는 상태가 없으며, 모든 데이터는 /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 "Beginning of custom commands"
  ## 첫 번째 가입에 대한 'From' 이메일 주소를 설정하려면 주석을 해제하고 변경하세요:
  ## 첫 번째 가입 이메일을 받은 후, 해당 줄의 주석을 다시 활성화하세요. 한 번만 실행하면 됩니다.
  - exec: rails r "SiteSetting.notification_email='discourse@zoho.fairbnb.community'"
  - exec: echo "End of custom commands"

Traefik 대시보드를 서브도메인을 통해 사용 가능하게 하려던 중 문제가 발생했으며, Discourse는 여전히 접근할 수 없습니다. 관련 링크: Discourse with Traefik 2.0 - Traefik v2 - Traefik Labs Community Forum
아래는 제가 사용하고 있는 설정입니다.

  1. 주석이 포함된 경우

    docker-compose: traefikV2_docker-compose.yaml
    # https://stackoverflow.com/questions/49718431/docker-compose-yml-file-naming-convention
    version: "3.7"
    
    services:
      traefik-reverse-proxy:   
        # 공식 v2.0 Traefik docker 이미지
        #image: traefik:latest 
        #image: traefik:v2.0
        image: traefik:v2.1.1
        container_name: traefik
        #command: 
        ## 사용자 지정 traefik 설정 파일을 사용하려면 로컬 경로를 선언하고 호스트의 해당 위치를 마운트해야 합니다. volumes 섹션을 참조하세요.
        #- --configFile=/etc/traefik/traefik-config.yaml
        
        ports:
          # HTTP 포트
          - 80:80
          # HTTPS 포트
          - 443:443
          # Web UI (--api.insecure=true로 활성화됨)
          #- "8080:8080"
        
        volumes:         
        # 구문 --> host-location:path-in-container, https://docs.docker.com/compose/compose-file/#volumes 참조
          # Traefik이 Docker 이벤트를 수신할 수 있도록
          - /var/run/docker.sock:/var/run/docker.sock
          # 로그 파일의 저장 위치를 호스트에 마운트하여 호스트에서 읽을 수 있도록 함
            # https://unix.stackexchange.com/questions/104936/where-are-all-the-posibilities-of-storing-a-log-file 기준 선택
          - /var/log/traefik:/var/log
          # 인증서의 저장 위치를 호스트에 마운트하여 호스트에서 읽을 수 있도록 함
            # https://www.getpagespeed.com/server-setup/ssl-directory 및 https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux 기준
          - /etc/ssl/certs/traefik/letsencrypt:/etc/ssl/certs/letsencrypt
          # 사용자 지정 "traefik.toml"을 사용하므로 traefik 컨테이너에 마운트해야 합니다(또는 그곳에 저장). 다음을 결합하여 사용:
            # 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
          
       # OS 정보와 HTTP 요청을 출력으로 표시하는 작은 Go 웹 서버
       #  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: {}   
    # 대시보드 활성화. 
      ## 8080 포트에서 Web UI 활성화. Traefik은 기본적으로 API 요청을 위해 8080 포트에서 수신합니다. traefik이라는 이름의 entryPoint에서 API를 직접 활성화합니다. (기본값: false) --> 포트 '8080'v= entryPoint 'traefik', --api를 오버라이드합니다.  
      #insecure: true
      ## 대시보드 활성화. (기본값: true)
      # dashboard: true
      # 디버깅 및 프로파일링을 위한 추가 엔드포인트 활성화. 
       debug: true    
      
    providers:
    # providersThrottleDuration: 42
      docker:
        #constraints: foobar
        ## 프로바이더 감시. (기본값: true)
        #watch: true
        ## Docker 서버 엔드포인트. tcp 또는 unix socket 엔드포인트일 수 있습니다. (기본값: unix:///var/run/docker.sock)
        #endpoint: unix:///var/run/docker.sock
        #defaultRule: foobar
        #tls:
          #ca: foobar
          #caOptional: true
          #cert: foobar
          #key: foobar
          #insecureSkipVerify: true
        # 기본적으로 컨테이너 노출. (기본값: true) / 기본적으로 감지된 모든 컨테이너에 대한 라우트가 생성됩니다. Traefik의 서비스 디스커버리 범위를 제한하려면, 즉 일부 컨테이너에 대한 라우트 생성을 허용하지 않으려면 두 가지 다른 방법으로 수행할 수 있습니다. generic exposedByDefault(traefik.enable에 의해 오버라이드됨) 또는 constraints 기반의 더 세밀한 granular 메커니즘.
        exposedByDefault: false
        #useBindPortIP: true
        #swarmMode: true
        # 기본적으로 사용되는 Docker 네트워크.
        network: bridge_proxy_traefikv2
        # swarmModeRefreshSeconds: 42  
    
    현재 미사용-metrics:    # 이는 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 로그 파일 
      # 로그의 디버그 레벨 설정
      level: DEBUG
      # 컨테이너 내부의 저장 위치 정의. 로그 파일은 컨테이너 내부에 작성됩니다. 호스트에서 사용 가능하게 하려면 마운트해야 하며, docker-compose 파일의 volumes 섹션을 참조하세요.
        # https://unix.stackexchange.com/questions/104936/where-are-all-the-posibilities-of-storing-a-log-file 기준 선택
      filePath: /var/log/traefik-log.log
      # Traefik 로그 형식: json | common (기본값: common)
      #format: common
    
    accessLog:      
    # 접근 시도 로깅   
      # 컨테이너 내부의 저장 위치 정의. 로그 파일은 컨테이너 내부에 작성됩니다. 호스트에서 사용 가능하게 하려면 마운트해야 하며, docker-compose 파일의 volumes 섹션을 참조하세요.
        # https://unix.stackexchange.com/questions/104936/where-are-all-the-posibilities-of-storing-a-log-file 기준 선택  
      filePath: /var/log/traefik-access.log
      # 액세스 로그 형식: json | common (기본값: 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
       #
       
    현재 미사용-tracing:    # 이는 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
       #
    현재 미사용-hostResolver:     # 이는 Notepad++에서 주석 영역을 접기/펼치기 위해 존재합니다.
    #hostResolver:
    #  cnameFlattening: true
    #  resolvConfig: foobar
    #  resolvDepth: 42
      #
    certificatesResolvers:
      tlsChallenge_letsencrypt:
        acme:
          email: my.secret@gmail.com
          # 사용할 CA 서버. (기본값: https://acme-v02.api.letsencrypt.org/directory)
          #caServer:        
          # https://www.getpagespeed.com/server-setup/ssl-directory 및 https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux 기준 선택된 위치
          storage: /etc/ssl/certs/letsencrypt/acme.json
          # 인증서 개인 키 생성에 사용되는 KeyType. 허용 값: 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'. (기본값: 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. 주석이 없는 경우

    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)에 답글을 남기는 것입니다.

감사합니다 ot :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"
        ## Lets Encrypt(https)를 추가하려면 아래 두 줄의 주석을 해제하세요
          #- "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을 얻기 위해 처음에 standalone으로 설치했기 때문에 제 설치 환경에서 해당 부분이 주석 처리되어 있지 않다는 것을 알게 되었습니다. 처음에 제가 주석 처리를 잊어버린 것입니다. 다른 사람들이 같은 문제에 빠지지 않도록 방지할 수 있을 것입니다.

당연합니다.

Traefik의 정적 설정은 표시되지 않나요?

모두에게 좋은 소식입니다! http://forum.fairbnb.community/ 에 접속할 수 있습니다.

app.yml에서 최소한의 변경 사항만 적용하여 HTTP로 서빙되도록 구성한 내용입니다. HTTPS 설정은 주말에 자세히 살펴보겠습니다.

templates:
    - "templates/postgres.template.yml"
    - "templates/redis.template.yml"
    - "templates/web.template.yml"
    - "templates/web.ratelimited.template.yml"
    ## 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

SSL의 경우 Traefik + Let’s Encrypt만 구성하면 됩니다. Discourse SSL을 사용할 필요가 없습니다.

Traefik은 모든 컨테이너에 대한 암호화를 관리합니다.

현재 저는 traefik 1.6을 사용 중이므로, traefik v2에서 이를 활성화하는 방법을 아직 잘 모릅니다.

네, Run other websites on the same machine as Discourse 를 확인해 보세요. 하지만 discourse는 클라이언트가 프록시를 통해 https로 통신할 때 특정 헤더 정보를 기대하는 것 같습니다.

간략히 읽어봤습니다. 평범한 사용자가 이해할 수 있는 텍스트로 번역해 보겠습니다.

네, Redirecting... 도 참고하세요. 처음에는 https를 바로 시작했고 인증서 생성에도 성공했지만, 거기까지였습니다. 이제 그때 이후로 쌓은 지식과 맞추어야 합니다.

즉, 포럼에 접속하기 위해 https를 사용하시는 거죠?
Traefik과 Discourse 설정을 공유해 주시겠습니까? 더 많이 공유해 주실수록 주말에 제게 더 쉬울 것입니다.
v1에서 v2로 전환하는 가이드는 Redirecting... 에 나와 있지만, 주말에 여기서 설명을 시도해 보겠습니다.

이것은 내 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)를 추가하려면 아래 두 줄의 주석을 해제하세요
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## 이 컨테이너가 노출해야 하는 TCP/IP 포트는?
## Apache나 nginx 같은 다른 웹서버와 포트를 공유하려면
## 자세한 내용은 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: {}

안녕하세요,

이 포스트를 가이드로 사용하여 Traefik과 함께 Discourse를 설정했습니다. 저는 이미 다른 웹 앱과 Traefik을 함께 사용 중입니다.

forum.private.com 을 방문하면 “404 페이지를 찾을 수 없음” 오류가 발생합니다.

Traefik 대시보드의 서비스 탭에서 discourse@docker 와 discourse_secure@docker 를 볼 수 있는 것으로 보아 일부는 작동하는 것 같습니다.

그러나 라우터 탭에는 discourse 관련 항목이 없습니다.

app.yml 파일에 적용한 변경 사항은 다음과 같습니다. 주로 위에 링크된 포스트를 기반으로 작성했으며, 하단의 docker 인자에 공개 포트(exposed port)를 추가했는데, 이렇게 하면 위에서 언급한 서비스들이 열렸습니다. 도움을 주시면 감사하겠습니다!

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 # <== traefik의 프로바이더로 docker 활성화
      - --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 # <== web이라는 이름의 :80 포트 엔트리포인트 정의
      - --entrypoints.web-secured.address=:443 # <== web-secured라는 이름의 :443 포트 https 엔트리포인트 정의
      ## 인증서 설정 (Let's Encrypt) -  https://docs.traefik.io/https/acme/#configuration-examples ##
      - --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== ACME 인증서 생성 및 갱신을 위해 TLS-ALPN-01 활성화
      - --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 # <== traefik을 web 네트워크에 배치하여 이 네트워크의 컨테이너에 접근 가능하도록 함
    labels:
    #### 라벨은 이 컨테이너에 대한 traefik 프록시의 동작과 규칙을 정의합니다 ####
      - "traefik.enable=true" # <== 대시보드 확인 및 서브도메인 할당을 위해 traefik 자체에 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)를 추가하려면 아래 두 줄의 주석을 해제하세요
  #- "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%로 설정하세요.
  ## bootstrap이 감지된 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

  ## 동시 웹 요청을 얼마나 많이 지원할 수 있습니까? 메모리와 CPU 코어 수에 따라 다릅니다.
  ## bootstrap이 감지된 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 "Beginning of custom commands"
  ## 첫 번째 가입 시 'From' 이메일 주소를 설정하려면 주석을 해제하고 변경하세요:
  ## 첫 가입 이메일을 받은 후, 다시 주석 처리하세요. 한 번만 실행하면 됩니다.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

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"

감사합니다