Advertencia: Si no te sientes cómodo trabajando como administrador de sistemas Linux y no tienes experiencia con contenedores Docker, pasar a una implementación de múltiples contenedores te causará dificultades. Tanto el personal como los voluntarios aquí te pedirán apropiadamente que regreses a una implementación independiente de un solo contenedor gestionada completamente por el script
launcher.Si pasas a una implementación de múltiples contenedores y tu sistema se rompe como resultado, es probable que te encuentres con la oportunidad de quedarte con ambas partes rotas. Si lees las instrucciones a continuación y te parecen magia, en lugar de aclarar cómo funcionan realmente las cosas dentro de los contenedores, corre, no camines, hacia tu implementación independiente predeterminada más cercana y te harás un favor.
El método recomendado para migrar de una implementación de un solo contenedor a una de múltiples contenedores es esencialmente:
- Haz una copia de seguridad de tu Discourse
- Tira todo a la basura
- Comienza de cero con una implementación de múltiples contenedores
- Restaura tu copia de seguridad
Si, como yo, tienes un sitio grande que tarda horas en restaurarse, quizás te preguntes si hay una forma más rápida. ¡No te preguntes más! Migré de una implementación independiente a una implementación de tres contenedores (web, datos y Redis) en menos tiempo del que normalmente tarda ./launcher rebuild app para ese sitio. (12 minutos de tiempo de inactividad total, cuando reconstruir la aplicación a veces ha tomado más de 30 minutos.) Basado en mi experiencia, en el futuro mantendría Redis junto con Postgres en un solo contenedor data.
Si haces esto, asumes la responsabilidad de saber cuándo necesitas reconstruir tus otros contenedores (datos y, si eres tan imprudente como yo y separas Redis, también Redis). Ya no obtendrás actualizaciones gratuitas de todo con ./launcher rebuild app. Si no tienes los recursos para gestionar este proceso, utiliza una implementación independiente o compra Discourse alojado.
Prueba
No utilices este proceso para migrar a múltiples contenedores a menos que, después de leerlo, ahora entiendas también cómo te indicaría cómo migrar rápidamente de múltiples contenedores a uno solo. Si esto no es obvio para ti después de leer esto, entonces esta publicación es una tecnología suficientemente avanzada (es decir, indistinguible de la magia), y es posible que tampoco reconozcas si este proceso se rompe a mitad de camino, por lo que podrías terminar con un Discourse roto que no reconocerás hasta mucho después. Si eso sucede, te quedarás con ambas partes rotas. Si lo rompes, lo pagas, como dicen.
Copia de seguridad
Haz una copia de seguridad primero y activa las copias de seguridad de miniaturas primero para que no tengas que reconstruirlas todas al restaurar. Si cometes un error aquí, fácilmente entrarás en una situación donde la forma más fácil, segura y rápida de recuperarte es cambiar al método normal. Prepárate para volver al método recomendado si algo sale mal.
Descarga tu copia de seguridad. Los comandos a continuación implican mover archivos dentro de los datos de Discourse, y si cometes un error, quizás hayas eliminado tu copia de seguridad. Así que descárgala. Además, si tu copia de seguridad no incluye las subidas, respáldalas también. También se encuentran en el lugar donde moverás archivos.
En serio, haz una copia de seguridad.
Cuando hice esto, primero hice una copia de seguridad y luego una copia de seguridad remota del sistema antes de continuar.
Configurar nueva configuración de múltiples contenedores
Necesitarás al menos containers/web_only.yml y containers/data.yml, y si también quieres separar Redis, también containers/redis.yml. Comienza copiando samples/data.yml (y opcionalmente samples/redis.yml) al directorio containers/.
Si estás desplegando Redis por separado, elimina la plantilla de Redis de la parte superior del archivo containers/data.yml. (Pero no hagas eso sin una buena razón; es solo trabajo extra.)
Tienes dos formas de crear web_only.yml:
- Copia
samples/web_only.ymlacontainers/; luego compara ambos concontainers/app.yml, preservando cualquier configuración de Postgres enparams:en tu nuevocontainers/data.yml- Copia cualquier
params:para Postgres decontainers/app.ymlacontainers/data.yml - Crea una contraseña única para reemplazar
SOME_SECRET
- Copia cualquier
- Alternativamente, copia
containers/app.ymlacontainers/web_only.ymly compáralo consamples/web_only.yml:- Elimina cualquier referencia a las plantillas de Postgres y Redis
- Elimina toda la sección
params:que solo tenía configuraciones de Postgres - Agrega una sección
links:tal cual desamples/web_only.ymlo modificada (ver abajo) si estás desplegando Redis en un contenedor separado - Agrega una sección de base de datos de
samples/web_only.ymly crea una contraseña única para reemplazarSOME_SECRET - Cambia las definiciones de volúmenes de
standaloneaweb_only
Aquí está la sección links: que debes usar si estás separando Redis en su propio contenedor en lugar de usar la opción razonable por defecto de agruparlo con Postgres en el contenedor de datos:
# Usa la clave 'links' para vincular contenedores, es decir, usa la bandera --link de Docker.
links:
- link:
name: data
alias: data
- link:
name: redis
alias: redis
El enlace redis no es necesario si estás combinando los contenedores de Redis y Postgres en un único contenedor de datos; esto es para mostrar lo que harías.
Aquí hay una copia de la configuración actual de Postgres en env en samples/data.yml que necesitarás cambiar SOME_SECRET en:
## TODO: configurar la conectividad a las bases de datos
DISCOURSE_DB_SOCKET: ''
#DISCOURSE_DB_USERNAME: discourse
DISCOURSE_DB_PASSWORD: SOME_SECRET
DISCOURSE_DB_HOST: data
## Si usas un único contenedor de datos+Redis, lo siguiente será "data"
DISCOURSE_REDIS_HOST: redis
Ten en cuenta que para una implementación normal (no multisitio) no necesitarás modificar ninguna otra línea. DISCOURSE_DB_SOCKET es para un socket de dominio Unix para Postgres, no es un número de puerto.
Aquí hay un ejemplo del cambio en la definición de volúmenes al final de web_only.yml que necesitarás usar si lo copias de app.yml en lugar de de samples/web_only.yml:
@@ -75,10 +80,10 @@
## El contenedor Docker es sin estado; todos los datos se almacenan en /shared
volumes:
- volume:
- host: /var/discourse/shared/standalone
+ host: /var/discourse/shared/web_only
guest: /shared
- volume:
- host: /var/discourse/shared/standalone/log/var-log
+ host: /var/discourse/shared/web_only/log/var-log
guest: /var/log
Ahora establece la misma contraseña secreta que usaste en containers/web_only.yml en containers/data.yml en lugar de SOME_SECRET.
Ahora estás listo para la migración.
Ahora es cuando tomas y descargas tu copia de seguridad final antes de intentar la migración rápida. Recuerda, si algo sale mal aquí, inmediatamente ve al método recomendado. No puedo enfatizarlo lo suficiente.
Contenedores de datos (Postgres) y Redis separados:
cd /var/discourse
./launcher stop app
cd shared
mkdir data
mkdir redis
mv standalone/postgres_* data/
mv standalone/redis_data/ redis/
mv standalone web_only
mkdir -p data/log/var-log
mkdir -p redis/log/var-log
cd ..
./launcher destroy app
./launcher bootstrap data
./launcher bootstrap redis
./launcher start redis
./launcher start data
./launcher bootstrap web_only
./launcher start web_only
Contenedor de datos combinado Postgres+Redis:
cd /var/discourse
./launcher stop app
cd shared
mkdir data
mv standalone/postgres_* data/
mv standalone/redis_data/ data/
mv standalone web_only
mkdir -p data/log/var-log
cd ..
./launcher destroy app
./launcher bootstrap data
./launcher start data
./launcher bootstrap web_only
./launcher start web_only
También ten en cuenta que si anteriormente configuraste nginx externo, necesitarás cambiar la ruta proxy_pass para que coincida con la nueva ubicación del socket web_only; por ejemplo, de http://unix:/var/discourse/shared/standalone/nginx.http.sock: a http://unix:/var/discourse/shared/web_only/nginx.http.sock:.
Para mí, en una VM de 2 núcleos con 4 GB de RAM y un sitio con copias de seguridad de 600 MB sin descargas, este proceso resultó en 12 minutos de tiempo de inactividad. Tus resultados pueden variar.
Ten en cuenta que nada de esto hasta ahora actualiza el launcher. Es posible que no estés actualizado. (Por ejemplo, ejecuté esto después de que estuviera disponible la actualización de Postgres 12, pero antes de haberla aplicado. Este proceso me dejó con Postgres 10. Luego, lo siguiente que hice fue reconstruir la aplicación de datos, lo que actualizó el launcher y me llevó exitosamente a través del proceso de actualización de Postgres 12.)
Qué hacer en futuras actualizaciones
Después de esta migración, si necesitas actualizar Redis o datos, primero debes detener la aplicación web. Esto se vería algo así:
./launcher stop web_only
./launcher rebuild data # y/o redis
./launcher rebuild web_only
Ten en cuenta que si reconstruyes el contenedor data (o postgres, o redis) necesitarás crear un nuevo contenedor web para volver a conectarlo con el nuevo contenedor de datos. Puedes hacerlo ya sea reconstruyendo web_only o, si no crees que necesitas reconstruirlo, un ./launcher destroy web_only; ./launcher start web_only hará el trabajo (y si obtienes un error sobre «falta el contenedor de datos» o similar, esto es lo que necesitas hacer).
Sin embargo, cuando ni Postgres ni Redis necesitan una actualización, es mucho más rápido no tener que reconstruir esos contenedores, y la mayoría de las reconstrucciones de aplicaciones son simplemente ./launcher rebuild web_only.
Alternativamente, para aún menos tiempo de inactividad (reportado variadamente entre 15 segundos y 2 minutos):
./launcher bootstrap web_only
./launcher destroy web_only && ./launcher start web_only
Nuevamente, al pasar a una implementación de múltiples contenedores, el seguimiento de cuándo es apropiado es ahora tu trabajo. Recibirás notificaciones en la consola de Administración sobre actualizaciones, pero solo se aplicarán al contenedor web_only. Nada te dirá cuándo necesitas actualizar Postgres o Redis. Si haces esto, lee la categoría de Anuncios antes de cada actualización de versión que realices, y lee las notas de la versión para cada nueva versión a la que estás actualizando o a través de la cual pasas. Es decir, si saltas una actualización de versión, no te saltes la lectura de las notas de la versión de la versión a la que saltaste la actualización. (Considera configurar una vigilancia en las notas de la versión o suscribir tu lector de feeds a https://meta.discourse.org/tag/release-notes.rss para mantenerte actualizado.)
Ten en cuenta que reconstruir el contenedor web_only requiere que la base de datos esté en ejecución, por lo que no puedes acelerar las cosas reconstruyendo los dos o tres contenedores en paralelo. Si vas a reconstruirlos todos cada vez, quédate con la implementación independiente estándar recomendada; será más rápida que manejar múltiples contenedores.
Revisión de la copia de seguridad
Si haces copias de seguridad de las subidas por separado de la base de datos, espero que tengas un régimen de copias de seguridad remotas basado en archivos para las subidas para que estén respaldadas para restaurar en caso de desastre.
Revisa tu implementación de copias de seguridad remotas para asegurarte de que hará copias de seguridad de las subidas en /var/discourse/shared/web_only en lugar de en /var/discourse/shared/standalone para que mantengas tus copias de seguridad actualizadas en tu nueva implementación de múltiples contenedores.