Actualmente administro dos foros de Discourse separados, ambos alojados en sus propias instancias de Scaleway y actualizados de la siguiente manera:
# Actualizar la configuración de Docker de Discourse
cd /var/discourse
git pull origin master
# Reconstruir Discourse
/var/discourse/launcher rebuild app
Esto deja el foro fuera de servicio durante unos 5 a 15 minutos cada vez.
Uno de los sitios está detrás del proxy de Cloudflare, por lo que sirve su caché offline sin problemas. Sin embargo, el otro no utiliza Cloudflare.
Me pregunto si Discourse podría exportar un sitio estático que contenga, por ejemplo, solo los hilos públicos para un usuario anónimo, con los botones de interacción deshabilitados y un banner en la parte superior que diga: “Este sitio web está actualmente en modo de solo lectura ya que está en proceso de actualización”, y luego servir ese contenido mientras el foro se actualiza. Una vez que el foro vuelva a estar en línea, se eliminaría la caché estática.
Si el DNS está gestionado por Cloudflare (incluso si no utiliza el proxy), generalmente se actualiza en cuestión de segundos. Durante la actualización, podrías apuntar el dominio a otro servidor (como una página de mantenimiento en Netlify/Vercel/Firebase/Surge/etc., donde todas las rutas apunten a un archivo index.html).
Aún no lo he probado, pero podría ser posible servir temporalmente otro backend utilizando resolveOverride en un Worker de Cloudflare (función “sin servidor”).
Sí, ya sea un cambio de DNS o iniciar un contenedor temporal de Docker con nginx escuchando en el mismo puerto para servir algo, esa es la parte sencilla.
En este momento, lo más difícil es una exportación estática con la interactividad deshabilitada y un banner añadido, respetando las páginas de temas, publicaciones, categorías e índice (la búsqueda puede estar desactivada). Luego, integrar este reemplazo en el proceso de actualización, aunque eso es bastante sencillo.
Buscar en los foros sobre exportación estática no parece que sea algo común. Ya he creado un cliente de la API de Discourse para un proyecto anterior, así que podría programar algo que no emule el diseño, supongo.
Otro factor al servir una exportación estática para este propósito sería asegurarse de que las páginas estáticas no sean almacenadas en caché por los navegadores ni por los motores de búsqueda.
Si ejecutas una instalación de dos contenedores, el tiempo de inactividad es inferior a un minuto. O, si estás dispuesto a ejecutar un balanceador de carga, puedes hacerlo cero. Eso es más fácil de lo que describes.
Además, infórmate sobre SKIP_POST_DEPLOYMENT_MIGRATIONS=1. En resumen, estableces esa variable al reconstruir el contenedor principal para evitar que rompa la base de datos del existente; luego, una vez que tengas el nuevo en funcionamiento, realizas la migración nuevamente sin esa variable.