Digital Ocean Spaces no implementa la API de AWS S3 para la regla CORS

,

Sigo teniendo dificultades para mover las cargas a Spaces. Cuando se define s3_cdn_url, Discourse apunta al s3_cdn para los activos y estos no están allí. Intenté ejecutar rake s3:upload_assets y obtuve:

root@shadrack-rbx:/var/www/discourse# rake s3:upload_assets                                                             
instalando regla CORS
Subiendo: assets/vendor-3037640def3beef9cc83cef108868f2bac887cf141d032c6b7388c7879c19601.js
OPTS: {:cache_control=>"max-age=31556952, public, immutable", :content_type=>"application/ecmascript", :acl=>"public-read", :tagging=>""} # NOTA: Pfaffman añadió esta línea de depuración. . . 
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
(Vea el rastreo completo ejecutando la tarea con --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

Por cierto, esta configuración puede subir imágenes a S3 sin problemas.

Y, si esto funcionara, ¿los activos se enviarían a S3 durante el arranque? Realmente quiero mover este sitio a S3 (73 GB de imágenes) para cambiar a una configuración de servidor diferente. Spaces es atractivo porque tengo créditos de referencia y CDN gratuito. Pero quizás debería simplemente desistir y mudarme a 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?)

No estoy seguro de si tú (o alguien más) todavía tiene problemas con esto, o si lo siguiente lo resolvería, pero como me encontré con esto mientras solucionaba mi propio problema, pensé que lo compartiría:

  • Si estás usando Digital Ocean Spaces para almacenamiento S3, y
  • Tienes temas con fuentes cargadas, por ejemplo WOFF, que se copian al almacenamiento S3, y
  • Estás recibiendo errores de CORS al cargar las fuentes en tu sitio de Discourse, entonces –

Digital Ocean Spaces ahora tiene configuraciones de CORS en el Endpoint que usas para almacenamiento S3. Establece la URL de tu sitio de Discourse como Origen, GET como método permitido y un valor razonable como 86400 para el tiempo.

Así que la conclusión de todo el tema fue un malentendido.

Pasé un día completo probando la compatibilidad de Discourse con las ofertas de DO, y lo de CORS aquí fue una pista falsa.

El problema es que DO Spaces no implementa la cabecera tagging en su clon de S3.

La solución para la tarea upload_assets es bastante simple y está en una rama.

El problema es que realmente usamos tagging en otra tarea de rake, por lo que si usas DO Spaces, no podrás usar nunca la tarea s3:expire_missing_assets. Lo cual puede ser un compromiso “aceptable” para algunos.

Planeo actualizar y crear algunas nuevas guías sobre esto la próxima semana.

Uff, ¿podemos reportar esto a DO para que arreglen su clon?

Estoy documentando un gran experimento utilizando servicios de DO con Discourse (como el servicio Redis, el servicio PostgreSQL, el servicio Object Store y el servicio CDN), para que podamos presentar esto en un documento conciso. Ya he encontrado un problema mucho peor. Su CDN clon de S3 elimina el encabezado Content-Encoding de los archivos, por lo que no podemos servir nuestros archivos JavaScript comprimidos con GZip y Brotli, y simplemente rompe todo.

El mejor resultado a largo plazo para todos es que todas las clonaciones de AWS S3 sean realmente… precisas. Así que si podemos hacer seguimiento y presionar a los proveedores para que mejoren sus clonaciones, esa es la vía superior.

Efectivamente.

Eso sería fantástico, pero no me hago ilusiones.

Por otro lado, no pueden arreglar lo que no saben que está roto. Quizás esto les dé el impulso que necesitan.

Puse en contacto con Digital Ocean y parece que están ejecutando MinIO por detrás, y MinIO añadió soporte para etiquetas hace un mes. Tendrán soporte para esto tan pronto como lancen esta nueva versión.

Esto ya está funcionando.

Solo sigue Usar almacenamiento de objetos para cargas (clones de S3)