Definir enlaces DISCOURSE_S3_CDN_URL a activos en la URL de CDN de S3

I had this problem before and decided that I was crazy, confused, or the database on the site was suspect, but this is on a brand new site. Also, I was on Digital Ocean spaces, so I thought it might be a problem somehow.

I’m trying again to figure out how to keep images on AWS S3 like I think the Big Boys do.

Here’s what I have in the env section:

  DISCOURSE_S3_ACCESS_KEY_ID: 'key'
  DISCOURSE_S3_SECRET_ACCESS_KEY: 'lock'
  DISCOURSE_BACKUP_LOCATION: 's3'
  DISCOURSE_S3_BUCKET: 'lc-xyz'
  DISCOURSE_S3_BUCKET_NAME: 'lc-xyz'
  DISCOURSE_S3_BACKUP_BUCKET: 'lc-xyz/backups'
  DISCOURSE_S3_UPLOAD_BUCKET: 'lc-xyz/uploads'
  DISCOURSE_S3_CDN_URL: 'https://lc-rbx.s3.amazonaws.com'

When I include the s3 cdn url the site breaks because all of the links to the assets are on S3 like https://lc-xyz.s3.amazonaws.com/assets/plugin-third-party-01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b.br.js.

Because if you define s3 cdn url Discourse looks for the assets on the s3_cdn_url.

I did a rebuild, but the assets are still missing. I can do a

rake s3:upload_assets

Is there an after_bundling_assets stanza that I could add that to? (I know about after_db_migrate and after_bundle_exec, but don’t know if those would work.)

Do assets get produced some other time? (It would seem like when themes get modified assets would change.)

If I also had a “push CDN like normal”, would that keep this from happening?

Is there some best practice that I’m missing?

You can use after_assets_precompile as the hook for that rake task.

Aha! Thanks very much for that. Where does the list of those things live?

I’m still confused why this is necessary, especially since you seemed confused before. (Or maybe I should be happy that I can push all this stuff to S3, now that I know how to do it–And I think that it was you who said that one could use CloudFlare’s free CDN to front an AWS bucket.)

Estoy intentándolo de nuevo. Tengo subidas funcionando hacia S3. Eso funciona.

Configuré Cloudflare para que sirva el sitio a través de CDN. Si ingreso https://lc-XXX.literatehosting.com/uploads en la configuración del sitio s3_cdn_url, las nuevas subidas van al bucket de S3, la imagen se enlaza a la URL de la CDN y funciona.

PERO si intento establecer s3_cdn_url con una variable de entorno en app.yml (o editar config/discourse.conf a mano y ejecutar sv restart unicorn), todos los activos se cargan desde S3 (donde no están). Eso podría estar bien, pero si intento ejecutar rake s3:upload_assets, se queja de que S3 no está configurado.

Me topé con esto mientras trataba de resolver algunos nombres de configuración en conflicto.

Creo (y espero, porque eso significa que entiendo esto y no escribí tonterías absolutas en el hilo enlazado arriba) que si eliminas estas dos líneas:

DISCOURSE_S3_BUCKET: 'lc-xyz'
DISCOURSE_S3_BUCKET_NAME: 'lc-xyz'

Entonces puedes establecer DISCOURSE_S3_CDN_URL, y solo se utilizará para las subidas, no para los activos.

Creo que tú sí lo entiendes, y, gracias a ti, ¡yo también estoy al menos más cerca de entenderlo! ¡Muchas gracias!

Me he encontrado con esto y sigo muy confundido después de leer este hilo…

Estoy intentando servir las subidas a S3 (no los activos compilados) desde una CDN (CloudFront).

Si configuro “s3 cdn url” a través de la pantalla de configuración, funciona como se espera (bueno… excepto por System upload not using s3 cdn url).

Sin embargo, si lo configuro mediante DISCOURSE_S3_CDN_URL y reconstruyo, el frontend se rompe porque intenta cargar los activos compilados desde mi URL de CDN de S3.

Parece que DISCOURSE_S3_CDN_URL / s3_cdn_url solo deberían afectar a las subidas, y DISCOURSE_CDN_URL solo debería afectar a los activos.

Esa es mi experiencia también. Terminé creando un plugin para establecer S3_CDN_URL.

@pfaffman parece que esto debería presentarse como un error, ¿verdad?

Quizás. No es una característica que los autohospedadores normales vayan a utilizar con frecuencia, por lo que tendrá baja prioridad. Además, creo que pronto habrá un cambio en la forma en que funcionan la configuración global y los ajustes superpuestos por la global, así que probablemente se resolverá entonces.

Parece que el mismo problema me está rechazando aquí
@pfaffman necesito tu ayuda
¿Usas CloudFront para lograr la URL de CDN de dominio personalizado o simplemente usas el prefijo público de los objetos del bucket en la URL de CDN?

Acabo de encontrarme con esto. @pfaffman, ¿lograste resolverlo?

He logrado que las subidas funcionen configurando manualmente s3_cdn_url en la configuración del sitio, pero idealmente necesito poder establecer la variable de entorno de forma global al desplegar. Cuando lo hago, obtengo el mismo problema: Discourse intenta buscar los recursos en s3_cdn_url, lo cual me parece un error en discourse/lib/content_security_policy/default.rb at main · discourse/discourse · GitHub

Creo que acabo de establecer el valor en la base de datos.

Mi suposición es que la solución consiste en encontrar la tarea de Rake que subirá los activos a S3.

Me preguntaba si alguno de los @team podría confirmar si este es el comportamiento esperado, es decir, que no se puede usar un CDN de S3 (configurado globalmente) para las cargas sin que Discourse también busque los recursos allí. Parece un comportamiento inesperado, a menos que esté malinterpretando algo.

Sí, ese es el comportamiento.

Configurar un CDN de S3 lo utilizará para todo lo que sea un archivo estático, ya sean cargas o activos de JS.

Aquí tienes información al respecto; estuve lidiando con esto el mes pasado.

Lo solucioné configurando ambas variables (DISCOURSE_S3_CDN_URL y DISCOURSE_CDN_URL) y creando dos distribuciones de CloudFront: una para las subidas con el bucket S3 como origen, y otra para los activos con el servidor como origen.

Aquí está el código que utilizamos para esto:

Este es nuestro app.yml (lo llamamos web.yml); reemplazamos las variables en el momento de la compilación infra/modules/services/discourse/web.yml at master · debtcollective/infra · GitHub

Increíble. Muchas gracias. No parece haber mucha documentación al respecto en absoluto, y la configuración sugiere que solo puedes usar S3 para cargas, lo cual creo que es lo que nos está confundiendo a todos.

Tengo en mi lista escribir un howto sobre esto. Espero hacerlo para el fin de semana.

Sí, una vez que entiendes que necesitas dos distribuciones de CloudFront, tiene más sentido. También, recuerda subir los activos a S3 después de cada reconstrucción. Hay un problema con las actualizaciones desde Docker Manager donde necesitas ejecutar bundle exec rake s3:upload_assets manualmente dentro del contenedor Docker. Si haces una reconstrucción en su lugar, debería funcionar si agregas estas líneas a tu app.yml

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - 'bundle exec rake s3:upload_assets'

Esa tarea está indicando que no tengo S3 configurado. He reducido el problema a este método en global_setting.rb:

def self.use_s3?
    (@use_s3 ||=
      begin
        s3_bucket &&
        s3_region && (
          s3_use_iam_profile || (s3_access_key_id && s3_secret_access_key)
        ) ? :true : :false
      end) == :true
  end

¿Dónde se espera que esté definido GlobalSetting.s3_bucket? Por lo que veo, necesitamos establecer las variables de entorno DISCOURSE_S3_UPLOAD_BUCKET y DISCOURSE_S3_BUCKET. ¿Cuál es la diferencia entre ambas?