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?)

Не уверен, что у вас (или у кого-то ещё) всё ещё возникают проблемы с этим, или что приведённое ниже поможет их решить, но так как я столкнулся с этим при устранении своей проблемы, решил поделиться:

  • Если вы используете Digital Ocean Spaces для хранения S3, и
  • У вас есть темы с загруженными шрифтами, например WOFF, которые копируются в хранилище S3, и
  • Вы получаете ошибки CORS при загрузке шрифтов на вашем сайте Discourse, то —

В Digital Ocean Spaces теперь есть настройки конфигурации CORS для конечной точки, которую вы используете для хранения S3. Укажите URL вашего сайта Discourse как источник (Origin), GET в качестве разрешённых методов и что-то разумное, например 86400, для времени.

Итак, весь вывод по теме оказался недоразумением.

Я потратил целый день на тестирование совместимости Discourse с предложениями DO, и проблема с CORS здесь оказалась ложной тревогой.

Проблема в том, что DO Spaces не реализуют заголовок tagging в своём клоне S3.

Исправление для задачи upload_assets довольно простое и находится в ветке.

Проблема в том, что мы на самом деле используем tagging по-настоящему в другой задаче rake, поэтому при использовании DO Spaces вы никогда не сможете использовать задачу s3:expire_missing_assets. Для некоторых это может быть приемлемой компромиссной мерой.

На следующей неделе я планирую обновить и создать новые руководства по этой теме.

Ох, можем ли мы сообщить об этом в DO? Чтобы они исправили свой клон?

Я готовлю отчёт о крупном эксперименте с использованием сервисов DigitalOcean в связке с Discourse (например, сервис Redis, сервис PostgreSQL, сервис Object Store, сервис CDN), чтобы мы могли изложить это в кратком документе. Я уже обнаружил куда более серьёзную проблему. Их CDN-клон S3 удаляет заголовок Content-Encoding у файлов, из-за чего невозможно отдавать наши сжатые GZip и Brotli файлы JavaScript, и это ломает всё.

Лучший долгосрочный результат для всех — это чтобы все клонирования AWS S3 были на самом деле точными? Так что, если мы сможем напоминать провайдерам и подталкивать их к улучшению их клонов, это будет лучшим путем.

Действительно.

Это было бы замечательно, но я не буду надеяться на это.

С другой стороны, они не могут исправить то, о чём не знают, что сломано. Возможно, это даст им необходимый толчок.

Я связался с Digital Ocean, и, похоже, они используют MinIO «под капотом». Поддержка тегов в MinIO появилась месяц назад. Как только они выпустят эту новую версию, поддержка появится и у них.

Это уже работает.

Просто следуйте использованию объектного хранилища для загрузки (S3 Clones)