최근 업그레이드 후 CORS 오류로 모든 플러그인이 작동하지 않음

지난주부터 코어 플러그인 및 설치된 모든 플러그인이 포럼에서 활성화되어 있더라도 기능을 멈추었습니다. 처음에는 이전에 언급된 버그(FIX: Compile missing rollup plugin bundles on demand in development - #7 by david)와 관련이 있는 줄 알았지만, 이후 여러 번 업데이트를 실행해 보았음에도 문제가 해결되지 않았습니다. 이전에 사용되지 않던 사전 설치된 ‘User Notes’ 플러그인을 활성화해 보았지만, 어떤 사용자에게도 메모를 추가할 수 있는 옵션이 없습니다. 또한 Docker 매니저도 작동이 중단되어 모든 업데이트를 서버 레벨에서 실행해야 하며, 이로 인해 관리자 팀이 아니라 단 한 명만 업데이트를 적용할 수 있는 상황이 되었습니다.

해결책을 찾아보았지만, ‘플러그인이 자동으로 비활성화됨’ 또는 이와 유사한 내용만 찾을 수 있을 뿐, 이 문제처럼 구체적인 해결책은 없었습니다.

롤백은 가능한 한 피하고 싶지만, 현재로서는 마지막 수단이 될 것 같습니다. 가능한 해결책이나 우리가 살펴봐야 할 방향에 대해 조언해 주실 수 있을까요?

항상 그렇듯, 이곳의 모든 분들과 지속적인 지원에 감사드립니다. :smiley:

음. 이건 CDN 관련 문제인 것 같습니다:


CORS 무시 플러그인을 활성화했는데 스크립트는 성공적으로 로드되었지만, 플러그인에서 오는 눈에 띄는 변화는 보이지 않습니다. 이 방법을 시도해 보시고, 작동한다면 CDN에서 오류를 일으키는 원인을 찾아내실 수 있을 것입니다.

이 문제를 조사해 주셔서 정말 감사합니다. 주말에 몇 가지 테스트를 진행해 보고, 가능한 대로 업데이트를 알려드리겠습니다.

bunnycdn에서도 동일한 문제가 발생하고 있습니다. 최근 업데이트 전까지는 정상적으로 작동하고 있었습니다.

여기에서 설명된 대로 bunny.net의 CORS 헤더에 .js를 추가하는 것을 시도해 보았습니다:

그때와 마찬가지로, 지난 주에 6800ad3adf3ef9c3caeb9a4d849997c7a3dc98d7로 업그레이드한 시점에 이 문제가 왜 시작되었는지 이해할 수 없습니다.

제이, 감사합니다. 버니와 함께 말씀해 주신 수정 사항을 적용했고, 이제 모든 문제가 해결되었습니다! 이 문제를 도와주신 여러분께도 감사드립니다. 이제 포럼이 정상으로 돌아왔습니다. 물론, 가능한 한 정상적인 수준으로 말이죠 :smiley:

해결되었다니 다행이네요!

새로운 플러그인 시스템에서는 script type="module"을 사용하는데, 이 경우 올바른 CORS 헤더가 설정되어 있어야 합니다. 구식 script type="text/javascript"는 이러한 헤더가 필요하지 않습니다.

지난 몇 년간 우리는 다양한 시스템을 type="module"로 점진적으로 전환해 왔습니다. 테마는 이미 이를 사용하고 있었으며, highlightjs(다른 토픽에서 언급된 것)도 마찬가지였습니다. CDN에서 폰트를 로드하는 경우에도 CORS 요구 사항이 적용됩니다.

따라서 최근 플러그인 시스템의 변경 사항 이전에도 다른 부분에서 미묘하게 깨진 것이 있었을 가능성이 높습니다. 이제 CORS 설정을 완료하셨으므로 모든 것이 다시 정상 작동해야 합니다 :chefs_kiss:

아하. 그건 제가 절대 예상하지 못했을 부분입니다.

여러분께 안내드립니다. Azure Classic CDN을 사용 중이시라면 이 문제가 발생하기 시작했습니다. CDN 측에서 수정 사항을 시도하고 있지만, Classic CDN 대신 정식 Front Door로 마이그레이션해야 할 수도 있습니다.

네, Azure Classic CDN에서도 이 문제를 확인했습니다.

규칙 엔진에 새로운 규칙을 추가해야 합니다. 아래에 예시를 보여드립니다:

"rules": [

                        {

                            "name": "JSCORS",

                            "order": 1,

                            "conditions": [

                                {

                                    "name": "RequestUri",

                                    "parameters": {

                                        "typeName": "DeliveryRuleRequestUriConditionParameters",

                                        "operator": "Contains",

                                        "negateCondition": false,

                                        "matchValues": [

                                            "/assets/js/plugins/"

                                        ],

                                        "transforms": []

                                    }

                                }

                            ],

                            "actions": [

                                {

                                    "name": "ModifyResponseHeader",

                                    "parameters": {

                                        "typeName": "DeliveryRuleHeaderActionParameters",

                                        "headerAction": "Overwrite",

                                        "headerName": "Access-Control-Allow-Origin",

                                        "value": "https://forums.mycoolforum.com"

                                    }

                                },

                                {

                                    "name": "ModifyResponseHeader",

                                    "parameters": {

                                        "typeName": "DeliveryRuleHeaderActionParameters",

                                        "headerAction": "Overwrite",

                                        "headerName": "Content-Type",

                                        "value": "application/javascript"

                                    }

                                },

                                {

                                    "name": "CacheExpiration",

                                    "parameters": {

                                        "typeName": "DeliveryRuleCacheExpirationActionParameters",

                                        "cacheBehavior": "BypassCache",

                                        "cacheType": "All"

                                    }

                                }

                            ]

이상하게도 이 문제는 테마에는 영향을 주지 않고, 우리에게는 플러그인에만 영향을 미쳤습니다.

Cloudflare를 사용 중인 사용자들을 위해, 최근 CORS 관련 변경 사항에 대한 설명서나 가이드를 찾을 수 있는 곳이 있을까요?

@pfaffman @TomoftheFog @tanya_byrne @denvergeeks 여러분의 자산이 어떻게 구성되어 있는지 확인해 주실 수 있을까요? 단순히 CDN과 애플리케이션 서버만 사용하고 계신가요? 아니면 S3/S3 호환 스토리지에도 자산을 저장하고 계신가요?

S3/S3 호환 스토리지를 사용하고 계신다면, 불행히도 CDN 특정 구성을 추가하는 것이 유일한 신뢰할 수 있는 방법입니다. 이 주제가 S3 자산에 관한 것이라고 가정했는데, 이제 확신이 서지 않습니다.

애플리케이션 서버에 대해 단순한 CDN을 사용하는 사용자의 경우, 추가적인 구성 작업이 필요하지 않았어야 합니다. 테마 JavaScript 및 highlightjs 번들과 정확히 동일하게 ‘그저 작동해야’ 합니다. 하지만 우리의 기본 NGINX 구성에서 헤더가 실제로 누락되어 있었던 것 같습니다. 죄송합니다!

이것이 문제를 해결하고 다시 작동하게 만들 것입니다:

이 PR이 병합된 후에는 적용을 위해 ./launcher rebuild app 실행이 필요합니다. NGINX 구성 변경은 UI 업데이트 동안 적용되지 않습니다.

이 정보를 메인 토픽에 추가했습니다:

불편을 끼쳐드려 죄송합니다! 다양한 CDN 구성에 대해 더 광범위한 테스트를 진행했어야 했습니다. 재빌드 후에도 여전히 문제가 발생하고 있다면 알려주세요.

S3를 사용하지 않는 것을 확인합니다

해당 문제가 발생하는 것으로 알려진 모든 사이트가 S3를 사용하고 있습니다. 일부 CDN은 이미 목록에 JS가 포함되어 있었고, 일부는 그렇지 않았습니다. 그 이유를 모르겠지만, 아마도 연도에 따라 기본값이 변경되었기 때문일까요?

늦게 답변드려 죄송합니다. 저희는 S3를 사용하고 있습니다.

Cloudflare R2에서 커스텀 도메인과 함께 사용할 때 CORS 설정을 적용하는 데 어려움을 겪었습니다. 결국 CDN 도메인에 항상 올바른 헤더를 삽입하도록 헤더 변환 규칙을 사용해 문제를 해결했습니다. 다른 분들에게 도움이 될 수 있어 공유합니다.

이 문제를 발견한 이후에 또 다른 문제를 발견했습니다. 일부 사용자는 Preformatted Text 마크다운 버튼을 사용할 때 아바타 이미지를 볼 수 없습니다. highlight-js를 로드하려고 시도하다가 CORS 실패라는 오류가 발생합니다:

이것이 우리 측 문제인지 확실하지 않지만, 관련이 있을 수 있으니 모든 분에게 알리고자 합니다.

f.insertcred.it가 사용자의 S3 CDN이라는 가정 하에, HighlightJS는 S3 CDN이 아닌 '애플리케이션 CDN’에서 로드되어야 하므로 이는 다소 의외인 문제입니다. 제가 아는 한, 지난 몇 달간 highlightjs와 관련된 변경 사항은 없었습니다.

애플리케이션 CDN을 사용하고 계신가요? 아니면 S3 + S3 CDN만 사용하고 계신가요?

포럼의 헤드 관리자로부터 업데이트를 받았습니다:


제가 아는 한, 우리는 CDN 앱을 사용하고 있지 않습니다. app.yml에서 DISCOURSE_CDN_URL 주석 처리를 해제하지 않았습니다.

DISCOURSE_S3_ENDPOINT와 DISCOURSE_S3_CDN_URL과 같은 S3 변수만 사용하고 있습니다.

민감한 정보는 제거한 우리의 app.yml 파일입니다.

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  db_shared_buffers: "256MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

  ## Maximum upload size (default: 10m)
  upload_size: 20m

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

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  UNICORN_WORKERS: 4

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: forums.insertcredit.com

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'EMAIL'
  
  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: USERNAME
  DISCOURSE_SMTP_PASSWORD: "PASSWORD"
  DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  DISCOURSE_SMTP_DOMAIN: forums.insertcredit.com
  DISCOURSE_NOTIFICATION_EMAIL: noreply@forum.insertcred.it
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: nyc3
  DISCOURSE_S3_ENDPOINT: https://nyc3.digitaloceanspaces.com
  DISCOURSE_S3_ACCESS_KEY_ID: KEY_ID
  DISCOURSE_S3_SECRET_ACCESS_KEY: ACCESS_KEY_VALYE
  DISCOURSE_S3_CDN_URL: https://f.insertcred.it
  DISCOURSE_S3_BUCKET: insertcredit-forum
  DISCOURSE_S3_BACKUP_BUCKET: insertcredit-forum-backup
  DISCOURSE_BACKUP_LOCATION: s3
  DISCOURSE_S3_INSTALL_CORS_RULE: false

  DISCOURSE_CAN_PERMANENTLY_DELETE: true

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  LETSENCRYPT_ACCOUNT_EMAIL: EMAIL

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

  ## The maxmind geolocation IP address key for IP address lookup
  ## see https://meta.discourse.org/t/-/137387/23 for details
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-bbcode-color.git
          - git clone https://github.com/discourse/discourse-signatures.git
          - git clone https://github.com/discourse/discourse-chart.git
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets
          - sudo -E -u discourse bundle exec rake s3:expire_missing_assets

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

이 정보가 질문에 도움이 되기를 바랍니다. 주목할 점은 며칠 전 발생했던 아바타가 사라지는 문제에 대한 보고를 더 이상 받지 못하고 있다는 것입니다. 제 지식 범위 내에서 아무것도 변경되지 않았으므로, 이전 문제가 해결된 후 시간이 지남에 따라 자연스럽게 해결된 것이었는지, 아니면 단순히 소수의 사용자들에게만 해당되는 문제였는지 정확히 알 수 없습니다.

확인해 주셔서 다시 한번 감사합니다.