Cómo recopilar todos los activos estáticos (js, css) utilizados por Discourse

Estoy intentando configurar un CDN para mi foro. Dado que China ha prohibido Fastly y muchos servidores CDN, no puedo usarlos para acelerar mi foro. Después de hacer algunas investigaciones, me volqué hacia Jsdelivr, que puede servir archivos estáticos desde npm o repositorios de GitHub.

Sé que puedo usar DISCOURSE_CDN_URL en app.yml para configurar la URL. Pero antes de eso, debo recopilar todos los archivos estáticos (js, CSS) de mi foro y luego subirlos a GitHub para que Jsdelivr pueda acceder a ellos. Descubrí que los archivos estáticos en realidad se encuentran dentro del contenedor Docker:

/var/www/discourse/app/assets

Así que estoy pensando en copiar todos los archivos de esta ruta cada vez que reconstruyo la aplicación y luego subirlos a GitHub; creo que esta idea debería funcionar, pero la solicitud real contiene un nombre de hash largo que no sé cómo obtener. Por ejemplo,

ember_jquery.js se convertirá en
ember_jquery-8ef4e572f0bf9485e6ef9a35f088729735f82434cf495fbcd5acedefbcddb363.js

Mi pregunta es:

  1. ¿Cómo generar el nombre del archivo con hash?
  2. ¿Hay alguna otra forma de recopilar los activos estáticos?

Es un hash SHA1 del contenido del archivo. Se genera aquí:

Las versiones compiladas que se utilizan se colocan en /var/www/discourse/public/assets/.

Si agregas una sección a tu archivo app.yml, puedes realizar una acción después de que el contenedor se reconstruya. Por ejemplo, para subir a S3 utilizamos algo similar a:

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets

En tu caso, reemplaza la tarea de rake con los comandos que ejecutas para subir los activos compilados a GitHub cuando se construye el contenedor.

Gracias @schleifer. Tu respuesta es muy útil. Sin embargo, todavía tengo algunas preguntas de seguimiento:

  1. ¿Dónde puedo encontrar la documentación para hooks como after_assets_precompile? He buscado en la documentación de Docker y también en el repositorio de GitHub de Discourse, pero no encuentro ninguna información al respecto. ¿Tengo que configurar yo mismo los hooks llamados after_assets_precompile (¿cómo se hace?) o ya están configurados por Discourse, como after_code?

  2. Según entiendo, mi pseudocódigo se vería así:

     hooks:
       after_assets_precompile:
         - exec:
             cd: $home
             cmd:
               - entrar al contenedor de Docker
               - ir a `/var/www/discourse/public/assets/`
               - git add, commit y push al repositorio de GitHub
    

Gracias.

Es una buena pregunta, pero no tengo una respuesta concreta para ti.

El sistema de configuración utilizado dentro del contenedor es:
https://github.com/discourse/pups

El README allí describe cómo funcionan los hooks en general. Los hooks específicos disponibles dependen de cómo esté configurada tu instancia: el archivo principal app.yml incluye una o más plantillas. En la mayoría de los casos, una de ellas es web.template.yml:

Ahí es donde se define el hook assets_precompile (en la [L159] al momento de escribir esto). Según la documentación de Pups, puedes ejecutar otros comandos antes o después de que se complete con before_assets_precompile y after_assets_precompile, respectivamente.

Los comandos se ejecutan dentro del contenedor Docker, así que no tienes que hacer nada al respecto.

La directiva cd: puede apuntar directamente a /var/www/discourse/public/assets/ y cada línea en cmd se ejecuta desde ese directorio. (Advertencia: cada línea en un array cmd se ejecuta en una shell separada, como en un Makefile).

No estoy seguro de si el contenido de /var/www/discourse/public/assets/ se conservará entre compilaciones, por lo que es posible que tengas que crear el repositorio git local y forzar el push cada vez. La solución “más correcta” podría ser definir un volumen Docker en app.yml para el directorio de activos en un volumen Docker definido en app.yml como los demás y persistir fuera del contenedor.

Muchas gracias. También descubrí que algunos activos estáticos (como CSS) se colocan en /var/www/discourse/tmp/stylesheet-cache. Pero hay dos problemas adicionales:

  1. Los usuarios suben activos como avatares, los cuales también se sirven a través de la CDN después de configurar DISCOURSE_CDN_URL. Sin embargo, subir los activos a GitHub cada vez que un usuario hace una carga no parece una solución ideal.

  2. Cuando Discourse solicita un avatar de usuario como 2_2.png, realiza lo siguiente: 1) divide el nombre del archivo, 2) realiza algunas verificaciones y 3) calcula el nombre real del archivo usando hash. Si necesito servir avatares de usuario, debo implementar la misma lógica yo mismo, ya que no existe ningún archivo llamado 2_2.png.

Mi solución final es sencilla: 1) Agrego Nginx delante de mi foro, como en este post. 2) Recopilo todos los activos estáticos de la ruta mencionada anteriormente y los subo a GitHub. 3) En el archivo de configuración de Nginx, agrego algunas reglas como:

location ~/(stylesheets|assets) {
    return 301 https://cdn.jsdelivr.net/gh/my_github/my_repo/$request_uri;
}

Gracias de nuevo, @schleifer.