Error al construir la última versión

Hola. Recibo el siguiente error al ejecutar ./installer rebuild web_only en las últimas versiones de Discourse.

fs.js:114
    throw err;
    ^

Error: ENOENT: no such file or directory, open 'root='/assets',url='/assets/vendor-4681e47c140b5a5bea2bfb1fec89365858288a8ea0c21979c0167ad9b570ee3d.js.map''
    at Object.openSync (fs.js:438:3)
    at Object.writeFileSync (fs.js:1189:35)
    at done (/usr/lib/node_modules/uglify-js/bin/uglifyjs:516:20)
    at cb (/usr/lib/node_modules/uglify-js/bin/uglifyjs:324:39)
    at /usr/lib/node_modules/uglify-js/bin/uglifyjs:391:9
    at FSReqWrap.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:53:3)
rake aborted!
Errno::ENOENT: No such file or directory @ rb_file_s_size - /var/www/discourse/public/assets/vendor-4681e47c140b5a5bea2bfb1fec89365858288a8ea0c21979c0167ad9b570ee3d.js
/var/www/discourse/lib/tasks/assets.rake:268:in `size'
/var/www/discourse/lib/tasks/assets.rake:268:in `block (4 levels) in <top (required)>'
/var/www/discourse/lib/tasks/assets.rake:159:in `block in concurrent?'
/var/www/discourse/lib/tasks/assets.rake:259:in `block (3 levels) in <top (required)>'
/var/www/discourse/lib/tasks/assets.rake:250:in `each'
/var/www/discourse/lib/tasks/assets.rake:250:in `block (2 levels) in <top (required)>'
/var/www/discourse/lib/tasks/assets.rake:159:in `concurrent?'
/var/www/discourse/lib/tasks/assets.rake:247:in `block in <top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace)
I, [2019-12-11T22:53:15.806396 #18]  INFO -- : Downloading MaxMindDB...
Compressing Javascript and Generating Source Maps



FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake assets:precompile' failed with return #<Process::Status: pid 17151 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"assets_precompile", "cmd"=>["su discourse -c 'bundle exec rake assets:precompile'"]}
f565d457b97d7ff12a258b03a456563a5a0e928c707c70e194ef88ba170aaf3a
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one

He desactivado todos los complementos, pero sigue sin funcionar. ¿Alguien puede arrojar algo de luz sobre esto?

Ya hemos visto esto antes en otro lugar.

¿Puedes intentar lo siguiente?

./launcher cleanup
git pull
./launcher rebuild app

Si eso no funciona, intenta eliminar todos los contenedores de la máquina y todas las imágenes.

Gracias por la respuesta rápida, @sam. Lo intentaré.

Una pregunta rápida. Asumo que “git pull” obtiene la última versión de discourse-docker, ¿verdad?

En general, ¿es necesario actualizar discourse-docker y discourse al mismo tiempo?

Actualmente, no tengo discourse-docker controlado por git. En su lugar, descargo una revisión específica de discourse-docker (como un archivo Zip) al configurar el servidor y fijo la versión de discourse a un commit específico durante el despliegue.

La razón por la que hago esto es para intentar hacer que la compilación sea reproducible; es decir, ejecutar el mismo comando con la misma configuración y fuente en dos momentos diferentes debería producir el mismo artefacto. En general, esta es una buena idea y me ha sacado de muchos problemas operativos con otros software a lo largo de los años :wink: Esto se debe a que te da la capacidad de volver a una configuración conocida y estable.

Sin embargo, creo que estoy nadando contra la corriente con Discourse, ya que parece querer obtener las últimas versiones de varios componentes de software durante la compilación. Empiezo a preguntarme si mis intentos de hacer que la compilación sea reproducible realmente me están perjudicando.

Palabras muy ciertas. Has entrado en un estado completamente insostenible con este hackeo :flushed_face:

Te recomiendo que obtengas lo último de git lo antes posible.

Las imágenes antiguas de Docker de la base de Discourse son incompatibles con la versión actual de Discourse, además de que carecen de muchos parches de seguridad.

Gracias @sam. He hecho eso y ahora puedo compilar la nueva versión. Afortunadamente, todo esto estaba en beta, así que no ha habido ningún daño :slight_smile: Aunque no estoy seguro de que sea “trucos” querer una compilación repetible :thinking:

Lo que intento lograr aquí es la capacidad de volver a una versión conocida y estable. Supongamos que ejecuto ./launcher rebuild app en el momento t1 y Discourse funciona. Luego ejecuto ./launcher rebuild app en el momento t2 y algo sale mal. ¿Cómo puedo devolver el software a la versión anterior? Creo que podría aceptar que la compilación no sea repetible si pudiera volver a un estado conocido y estable. Dado que el launcher ya ha construido una imagen de Docker funcional en el momento t1, ¿es posible indicarle al launcher que use una imagen específica en lugar de la incorrecta que se construyó en el momento t2?

¿Alguna idea?

Disculpa si me he desviado un poco del tema; puedo volver a publicarlo si lo prefieres.

Si deseas compilaciones repetibles, debes fijar tu versión de Discourse a un SHA específico mediante la configuración de tu contenedor y cada plugin.

Esto significa que dejarás de recibir correcciones para Discourse, parches de seguridad para la imagen de Docker, etc., pero la compilación será bastante repetible.

Es posible que también necesites modificar las plantillas para fossilizar ciertos elementos y evitar que se apliquen correcciones de seguridad a las dependencias de apt.

Ok, ya he fijado la versión de Discourse a un commit específico y también puedo hacer esto para los plugins. Pero si no fijo también discourse-docker, ¿no se producirá una situación en la que discourse-base se actualice en cada compilación mientras que Discourse no? ¿No eso no resultará en una incompatibilidad similar pero al revés (porque discourse-base se adelantará a Discourse)?

Estoy confundido, ¿cómo apareció este error si tienes Discourse fijado en una versión antigua?

¿Quieres que se corrija si NGINX tiene una vulnerabilidad crítica?

El error apareció cuando avancé la versión fijada de Discourse desde 2.4.0.beta2 hasta 2.4.0beta8.

Por supuesto, me gustaría que se solucionaran las vulnerabilidades críticas en los sistemas de software dependientes cuando ejecuto una nueva compilación. ¡Suena fantástico!

Sin embargo, también me gustaría poder revertir en caso de que la nueva versión tenga fallos :slight_smile:

Déjenme poner un ejemplo concreto:

Supongamos que mi configuración está en el estado actual:

discourse: 2.4.0beta2 (fijada en web_only.yml)

Ejecuto ./launcher rebuild web_only y todo funciona.

Ahora mi sistema está en este estado:

discourse: 2.4.0beta2
discourse-docker: LATEST-AT-TIME-T1

Ahora cambio mi configuración a este estado:

discourse: 2.4.0beta8 (fijada en web_only.yml)

Ejecuto ./launcher rebuild web_only y algo se rompe.

Mi sistema ahora está en este estado:

discourse: 2.4.0beta8
discourse-docker: LATEST-AT-TIME-T2

Ahora quiero volver a la versión anterior para que todo vuelva a funcionar. Así que cambio la versión fijada de Discourse a 2.4.0beta2 y vuelvo a compilar. Sin embargo, al ejecutar ./launcher rebuild web_only, el sistema ahora está en este estado:

discourse: 2.4.0beta2
discourse-docker: LATEST-AT-TIME-T2

Aunque la versión fijada de Discourse es la misma, la versión de discourse-base (y el resto de discourse-docker, plantillas, el propio ./launcher, etc.) será diferente, por lo que no estaré regresando a un estado conocido y funcional, y temo que ni siquiera se compile.

Disculpen si soy lento aquí, todo lo que quiero es tener la capacidad de volver a un estado seguro en caso de que haya problemas durante una actualización. ¿Quizás volver a ejecutar ./launcher rebuild web_only no es la forma correcta de revertir aquí? Para otros sistemas que despliego, simplemente volvería a desplegar una imagen de Docker anterior. ¿Hay alguna forma de indicar al launcher que haga esto?

Sí, tienes que repensar tu proceso aquí. Las migraciones de nuestra base de datos no son reversibles.

Si quieres probar una actualización sin comprometerla, necesitas operar en un entorno de pruebas (sandbox) de staging.

Sí, entiendo que es difícil revertir una migración de base de datos. Obviamente, Discourse no está diseñado pensando en mi estrategia de gestión de lanzamientos y despliegue. Debería dejar de nadar contra la corriente.

Tengo un entorno de staging, así que simplemente abandonaré cualquier idea de construcción y despliegue repetibles, probaré en staging y luego cruzaré los dedos y los dedos de los pies al pasar a producción.

Gracias por tu ayuda @sam