Constructor de imágenes de Discourse para pipelines CI/CD de Gitlab

¡Hola!

Hemos creado un repositorio llamado RPS Discourse Image Builder que se utiliza para crear una imagen OCI de Discourse. Creo que esto podría ser útil para algunas personas que buscan esto. Principalmente lo hicimos para no tener que esperar a la implementación de Discourse, que lleva mucho tiempo, y para poder fijar versiones de Discourse de manera confiable.

Escribimos un script que utiliza el repositorio discourse_docker para construir la imagen con la versión estable de la manera más general posible.

También hay un archivo docker-compose que inicia las bases de datos necesarias para la compilación y la imagen de Discourse para pruebas, y la ejecuta para el desarrollo local. Esto se puede ejecutar en un runner de GitLab con el ejecutor shell, pero necesita un sistema con una versión de docker-compose que admita perfiles.

Enfoque

El script de compilación debe ejecutarse dentro de nuestras canalizaciones de CI/CD para que podamos actualizar fácilmente la versión, de modo que los ajustes adicionales se realicen en diferentes repositorios con Dockerfiles que se basan en la imagen creada por este repositorio.

Antecedentes

Discourse es un software muy bueno, pero no es muy fácil de implementar y fijar versiones. Este repositorio se utiliza para crear una imagen de Docker que se puede usar para implementar Discourse.

El problema es que Discourse tiene una forma muy particular de construir sus imágenes de Docker. Los desarrolladores de Discourse esperan que usted construya la imagen en la máquina de destino con su repositorio discourse_docker.

Ha habido largas discusiones sobre esto en el foro, TL;DR: Los desarrolladores principales de Discourse se niegan a admitir una imagen de Docker pública que pueda usarse para implementar Discourse. Quieren mantener el repositorio discourse_docker como la única forma oficial de implementar Discourse.

Las principales desventajas de este enfoque son:

  • No es posible, según nuestra experiencia, fijar versiones de Discourse de manera confiable.
  • Lleva mucho tiempo compilar la imagen y, cuando la imagen se compila, el servicio no está disponible. Además, Discourse tiene el ciclo de vida de desarrollo más largo de todos los servicios que admitimos.
  • Las bases de datos se gestionan de manera diferente a la de los proyectos habituales basados en Docker.
  • La historia de implementación oficial de Discourse es incompatible con los flujos de trabajo de desarrollo y las implementaciones basadas en OCI, como Kubernetes o incluso Docker-Compose.
  • El lanzador discourse_docker hace muchas suposiciones sobre el entorno en el que se está ejecutando. Por ejemplo, se niega a ejecutarse en Podman sin root con un error sobre volúmenes de almacenamiento faltantes sin poder omitir esto con un argumento o variable de entorno.
2 Me gusta

Hay un parámetro version en el archivo app.yml que se puede establecer en la versión que deseas ejecutar.

Usando la instalación oficial que se maneja mediante Moverse de un contenedor independiente a contenedores web y de datos separados.

Cierto, intentamos que sea fácil para los webmasters del tipo “arrastra y suelta el contenido de este archivo zip con FileZilla a través de FTP”, al tiempo que garantizamos que todos ejecuten versiones recientes, compatibles y parcheadas de todo el software de la pila, incluso sus bases de datos.

Para los administradores de Discourse más experimentados, apuntar a una base de datos gestionada externamente está a una variable de entorno de distancia según Configurar Discourse para usar un servidor PostgreSQL separado

Sí, el flujo basado en el lanzador no es compatible directamente con la orquestación de contenedores. Dicho esto, se puede hacer compatible ejecutando ./launcher bootstrap app y enviando la imagen resultante a un registro de contenedores y luego ejecutando dicha imagen a través de la orquestación.

Agradecemos una solicitud de extracción para hacer esto posible, ya que suena útil en general. pr-welcome

5 Me gusta

Intentamos eso para crear un despliegue desde 2.8, pero falla quejándose de una versión incorrecta de Discourse. Dado que ahora podemos reproducir esto en nuestro CI/CD, puedes ver el error aquí: docker-build (#4121616927) · Jobs · idcohorts / RPS / Discourse Image Builder · GitLab

Básicamente, eso es lo que estamos haciendo. :slight_smile:

Gracias, estoy en ello.

1 me gusta

Eso es porque Discourse 2.8 ya no tiene soporte, lo que significa que no hemos portado Ruby más reciente a él, y se ejecuta en una versión de Ruby que ya está EOL. Nadie debería ejecutarlo en producción.

1 me gusta

Hecho, ver add bypasses for unsupported docker versions by mkbrechtel · Pull Request #706 · discourse/discourse_docker · GitHub

2 Me gusta

Aún así, ni siquiera es técnicamente posible (solo cambiando el parámetro de versión), por lo que ya no podemos reproducir entornos antiguos.

bueno, puedes hacerlo, solo tienes que usar una imagen base más antigua.

¿Cómo lo haría? Busqué y no encontré una solución…

Literalmente hace referencia a la imagen base anterior (creada aproximadamente en la fecha del lanzamiento que está dirigiendo; obviamente, debe ser posterior)

Hay páginas (¡y páginas!) de ellas:

https://hub.docker.com/r/discourse/base/tags

1 me gusta

Pero si intentas fijar una versión demasiado antigua, puede que no funcione con versiones actualizadas de la imagen base de Discourse. No recuerdo ejemplos específicos, pero cosas como una versión antigua de Discourse no funcionarán con Ruby 3.2, por lo que (a veces) también necesitas fijar discourse_docker si fijas una versión antigua de Discourse.

La solución más segura y, en la mayoría de los casos, la menos derrochadora es construir una imagen y enviarla a un repositorio en lugar de construir una nueva imagen en cada despliegue. Y si tienes plugins, es probable que también necesites fijar cada uno de ellos.

He hecho esto para varios clientes para ECS, así como para k8s en GCP y AWS.

Estoy bastante seguro de que puedes si también fijas discourse_docker a la versión antigua. Como mencioné anteriormente, es más complicado con los plugins, ya que es probable que también necesites fijarlos a las versiones antiguas. Si realmente quieres mantener versiones antiguas, construirlas exactamente una vez y enviarlas a un repositorio es el camino a seguir. Estoy haciendo esto con un cliente para probar las rutas de actualización desde la producción actual a la última y está funcionando sin problemas.

1 me gusta