Digital Ocean Spaces don’t implement the AWS S3 API for the CORS rule

,

I’m still struggling getting uploads moved to Spaces. When s3_cdn_url is defined, discourse points to the s3_cdn for assets and they aren’t there. I tried `rake s3:upload_assets and get

root@shadrack-rbx:/var/www/discourse# rake s3:upload_assets                                                             
installing CORS rule
Uploading: assets/vendor-3037640def3beef9cc83cef108868f2bac887cf141d032c6b7388c7879c19601.js
OPTS: {:cache_control=>"max-age=31556952, public, immutable", :content_type=>"application/ecmascript", :acl=>"public-read", :tagging=>""} # NOTE: Pfaffman added this debug line. . . 
rake aborted!
Aws::S3::Errors::InvalidArgument: 
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/seahorse/client/plugins/raise_response_errors.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-s3-1.30.1/lib/aws-sdk-s3/plugins/sse_cpk.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-s3-1.30.1/lib/aws-sdk-s3/plugins/dualstack.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-s3-1.30.1/lib/aws-sdk-s3/plugins/accelerate.rb:35:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:20:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/aws-sdk-core/plugins/idempotency_token.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/aws-sdk-core/plugins/param_converter.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/aws-sdk-core/plugins/response_paging.rb:10:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/seahorse/client/plugins/response_target.rb:23:in `call'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-core-3.46.1/lib/seahorse/client/request.rb:70:in `send_request'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-s3-1.30.1/lib/aws-sdk-s3/client.rb:5856:in `put_object'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/aws-sdk-s3-1.30.1/lib/aws-sdk-s3/object.rb:928:in `put'
/var/www/discourse/lib/s3_helper.rb:44:in `upload'
/var/www/discourse/lib/tasks/s3.rake:38:in `block in upload'
/var/www/discourse/lib/tasks/s3.rake:37:in `open'
/var/www/discourse/lib/tasks/s3.rake:37:in `upload'
/var/www/discourse/lib/tasks/s3.rake:148:in `block (2 levels) in <top (required)>'
/var/www/discourse/lib/tasks/s3.rake:147:in `each'
/var/www/discourse/lib/tasks/s3.rake:147:in `block in <top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => s3:upload_assets
(See full trace by running task with --trace)
root@shadrack-rbx:/var/www/discourse# vi config/discourse.
discourse.conf           discourse.config.sample  discourse.pill.sample    
root@shadrack-rbx:/var/www/discourse# vi config/discourse.conf
root@shadrack-rbx:/var/www/discourse# rails c

FWIW, this config can upload images to S3 just fine.

And, if this were to work, would assets get pushed to S3 in bootstrap? I really want to get this site moved to S3 (73GB images) to move to a different server configuratoin. Spaces is appealing because I have referral credits and free CDN. But maybe I should just punt and move to AWS S3?

Why do you need to push assets to S3? Can’t they be served from a push CDN like normal? Uploads assets means JS files not uploads.

That’s what I thought, but what’s happening is that all the assets are linked to the S3 CDN url and they aren’t there. I’d assumed that they’d either be served by the CDN like normal (I have one site configured with regular CDN and it points to S3 cdn when that’s configured) or from local storage (I have another site configured with no regular CDN and when I have s3_cdn_url in global settings, all the assets are linked to the s3 CDN.

So, I either need to push assets to S3 or have Discourse not point to assets in S3. I don’t really care, but they need to be somewhere that they can be found, as without assets the whole site is hosed and I have to make changes in console.

Making sure you saw this @pfaffman because this topic makes very little sense the way it is phrased now.

Do you mean “uploads” as in “uploaded files”?

No, I really mean assets (uploads seem fine). It seems that when GlobalSettings.s3_cdn_url is defined, discourse expects assets (i.e., the javascript stuff) to be in the S3 CDN, so the site is broken because none of the assets are available.

It makes zero sense to me either. :frowning_face:

I just set SiteSettings.s3_cdn_url (not in GlobalSettings) and assets seem to still be coming from the server, not the CDN. So maybe it’s a bug with GlobalSettings.s3_cdn_url?

Yup. Re-setting the value in discourse.conf does this:

All those red things link to the CDN for the assets.

I turned it back on/off and defining it as a global makes assets link to the s3_cdn_url.

So I guess the thing to do is configure those values in a plugin and hide them from the UX that way.

Looks like spaces don’t implement the AWS S3 API for the CORS rule. That is a must have since assets can contain fonts, and those really need CORS.

Maybe work on a way to disable the rules insertion and took care of that manually?

@rishabh did this already with the tombstone rule to allow our S3 compatibility with more providers, so makes sense to expand on that.

So if I want to move this site to S3 maybe I should just give in and stick this on AWS S3 and then stick CloudFlare or KeyCDN in front of it?

No.

That means that if you want to use the GlobalSettings for S3 in the current state you will need to deal with the missing feature in the S3-like service in Digital Ocean, patching around it somehow.

You already have a workaround (use a normal site setting), and we know that we need a setting to disable the CORS rule (pr-welcome for that).

Sorry I’m dense. I’ve been working on this off and on for months.

Ah, so as long as I don’t use GlobalSettings it’ll work just fine? (Because GlobalSettings also wants assets to be in S3?)

여러분(혹은 다른 분들)이 여전히 이 문제로 어려움을 겪고 있는지, 아래 내용이 해결책이 될지는 확실하지 않습니다. 하지만 제가 제 문제를 해결하던 중 이 내용을 발견해서 공유해 봅니다:

  • S3 스토리지로 Digital Ocean Spaces를 사용 중이고,
  • WOFF와 같이 업로드된 폰트가 포함된 테마가 있으며, 이 폰트들이 S3 스토리지로 복사되고 있고,
  • Discourse 사이트에서 폰트를 로드할 때 CORS 오류가 발생한다면 –

Digital Ocean Spaces는 현재 S3 스토리지로 사용하는 엔드포인트에 CORS 구성 설정을 제공합니다. Discourse 사이트 URL을 Origin으로, 허용 메서드로 GET을, 시간에는 86400과 같은 적절한 값을 설정하세요.

결국 이 토픽 전체가 오해에서 비롯된 것이었습니다.

DO(디지털오션) 서비스와의 Discourse 호환성을 테스트하는 데 하루 종일 시간을 보냈고, 여기서 언급된 CORS 문제는 사실 중요한 문제가 아니었습니다.

문제는 DO Spaces가 S3 클론에서 tagging 헤더를 구현하지 않고 있다는 점입니다.

upload_assets 작업에 대한 수정 방법은 비교적 간단하며, 해당 브랜치에 반영되어 있습니다.

문제는 다른 rake 작업에서 실제로 tagging을 사용하고 있기 때문에, DO Spaces를 사용하는 경우 s3:expire_missing_assets 작업을 사실상 사용할 수 없다는 점입니다. 이는 일부 사용자에게는 “허용 가능한” 타협점이 될 수 있습니다.

다음 주에 이 주제에 대한 가이드를 업데이트하고 새로운 가이드를 작성할 예정입니다.

으으, 이 문제를 DO에 보고할 수 있을까요? 그러면 클론을 수정할 수 있을 텐데.

DO 서비스(예: Redis 서비스, PostgreSQL 서비스, Object Store 서비스, CDN 서비스)를 Discourse와 함께 사용하여 진행한 대규모 실험에 대해 문서를 작성 중입니다. 이렇게 하면 이 내용을 간결한 문서로 전달할 수 있습니다. 이미 훨씬 더 심각한 문제를 발견했습니다. DO의 S3 호환 CDN이 파일의 Content-Encoding 헤더를 제거하기 때문에, GZip 및 Brotli로 압축된 JavaScript를 제공할 수 없고, 결국 모든 것이 깨집니다.

모두에게 장기적으로 가장 좋은 결과는 AWS S3 클로닝이 실제로… 정확해지는 것입니다. 따라서 프로바이더에게 클론의 품질을 개선하도록 꾸준히 요청하고 압박하는 것이 더 나은 방법입니다.

그렇습니다.

그렇게 되면 정말 훌륭할 텐데, 저는 기대를 품고 있지는 않습니다.

반면, 깨진 것을 모르면 고칠 수 없죠. 아마 이 일이 그들에게 필요한 자극이 되어줄 수도 있습니다.

Digital Ocean에 문의해 본 결과, 내부적으로 MinIO를 사용하고 있는 것으로 확인되었습니다. MinIO는 한 달 전부터 태그링(tagging)을 지원하고 있으며, 새로운 버전이 배포되는 대로 해당 기능을 지원할 예정입니다.

이제 정상적으로 작동합니다.

업로드용 객체 저장소 사용 (S3 클론) 문서를 그대로 따르시면 됩니다.