Avatares perdidos después de la restauración. ¿Cómo recuperarlos?

Buenos días @ariznaf,

Antes de llegar a esa conclusión, ¿podrías ir a todas tus instalaciones, acceder a la carpeta compartida de cada una de ellas y ejecutar el siguiente comando en cada instalación? Luego, por favor, comparte los resultados:

# du -sh uploads

Por ejemplo, en nuestras instalaciones, hice esto:

Instalación original:

# du -sh uploads
2.5G uploads

Instalación solo de socket (antes de solucionar el problema):

# du -sh uploads
444K uploads

Esto me dio la pista necesaria para ver que debía copiar manualmente la carpeta uploads; y, conociendo el problema, la solución es sencilla.

Si revisas todas tus diferentes carpetas uploads con du -sh uploads en todos los directorios compartidos, esto te dará una pista valiosa sobre lo que está ocurriendo.

Si son diferentes, sabrás que faltan algunas cargas y podrás corregirlo manualmente.

Si todas son iguales (poco probable), entonces el problema se vuelve más interesante :slight_smile:

He encontrado el problema (no la solución).
El problema no es la restauración en sí, sino el cambio del nombre del servidor.

Déjame explicar cómo realicé la restauración (por si acaso falta algún paso).

He descargado una copia fresca de Discourse desde GitHub.
Ejecuté el proceso de configuración de Docker.
Antes de ejecutar la aplicación y proceder a la restauración, edité app.yml para configurar el acceso al socket.
Y cambié el nombre del host a b.domain.com (en el original era a.domain.com).

Configuré el proxy inverso de Nginx usando SSL para dirigir el tráfico HTTPS del puerto 443 al socket de Discourse.
Luego reconstruí (launcher rebuild app) y reinicié Nginx (service nginx restart).
Accedí a https://b.domain.com para realizar la configuración inicial de Discourse.
Lo configuré para restaurar desde S3 y restauré la última copia de seguridad realizada de la base de datos y las cargas (sin miniaturas).
Después de la restauración, se cierra la sesión automáticamente.
Edité app.yml para copiar el archivo app.yml del sitio antiguo (con el fin de obtener la misma configuración y los mismos complementos).
Cambié el nombre del host a b.domain.com en app.yml.

De nuevo, una reconstrucción y un reinicio de Nginx.

EL PROBLEMA persiste: las imágenes de perfil (miniaturas) de todos los usuarios que han cambiado su perfil se han sustituido por esa imagen de perfil en blanco.
Nuestro logotipo en la esquina superior izquierda también falta.

@Stephen, force_https estaba activado (como estaba en el servidor original, sin problemas). Intenté activarlo y desactivarlo, sin ningún efecto. Lo he dejado activado, ya que queremos que nuestro sitio se acceda mediante HTTPS (de todos modos, el tráfico HTTP:80 tiene una redirección permanente en nuestra configuración de Nginx hacia HTTPS:443).

@riking, usé Sidekiq y ejecuté el trabajo avatarmissing, que pareció finalizar correctamente en unos pocos milisegundos. Por si acaso era un proceso largo, esperé casi 24 horas para ver si las imágenes de perfil se reconstruían.
Pero hoy tenemos el mismo problema: no hay imágenes de avatar (para las personas que subieron una imagen de perfil) ni imagen del logotipo.

Después de eso, intenté ver si el problema era el cambio de nombre, como sugirió @Stephen.

Cambie de nuevo el nombre del host en app.yml y en Nginx a a.domain.com (el original) y reconstruí y reinicié Nginx.
Modifiqué mi archivo local de hosts para que a.domain.com apuntara a la IP del nuevo servidor e intenté hacer un ping para verificar que estaba accediendo a la nueva IP.

¡Y VÍOLA! Allí estaban los avatares y nuestro perfil.

Así que el problema no es la restauración en sí; el problema es que de alguna manera la ruta completa de la URL se guarda y está intentando acceder a ellas desde el lugar incorrecto.
Es extraño de todos modos, ya que el servidor original está activo y funcionando (debería haber encontrado las imágenes incluso desde el lugar incorrecto, el servidor original en lugar del nuevo).

Pero de todos modos, el problema no está en el proceso de restauración ni en la necesidad de volver a subir las imágenes debido a algún tipo de corrupción.

El problema es el cambio en el nombre del servidor.

Ahora la pregunta es: ¿cómo se mueve un foro de Discourse de un dominio/nombre de host a otro?

He intentado cambiar nuevamente el nombre del host a b.domain.com.

Sin éxito.

Parece que cuando uso el nombre antiguo funciona (aunque ahora sospecho que está obteniendo imágenes y otros elementos del servidor antiguo que aún está en línea, ya que recibo nuevas publicaciones y notificaciones de publicaciones nuevas en el servidor antiguo, incluso aunque he cambiado la IP de a.domain.com en mi archivo hosts).

He seguido las instrucciones de esta publicación para cambiar el nombre del host:

Pensé que hacer que Discourse redirija a.domain.com a b.domain.com solucionaría el problema.
Incluso ejecuté rake posts:rebake, pero el resultado es el mismo.

He perdido los avatares y el logotipo, y las imágenes insertadas en las publicaciones también se han perdido.

Finalmente, como sugirió @neounix, descomprimí todas las cargas nuevamente para reemplazar el destino en shared/standalone/uploads/, pero sin éxito; los resultados son los mismos.

¿Realmente hay información valiosa en tu base de datos? Podría ser más fácil simplemente empezar de cero sin preocuparse por los cambios de servidor en absoluto.

¿Todos los datos y publicaciones desde el inicio del foro hace meses?

Como ya dije, he podido mover el servidor a otro deteniéndolo, copiando todos los datos a uno nuevo y reiniciándolo.

Pero el soporte me indicó que la forma correcta de hacerlo es mediante la copia de seguridad estándar y la restauración de la base de datos.

Estoy intentando hacerlo, pero cada vez surge algún tipo de problema.
También necesito un servidor para pruebas, a fin de verificar el impacto de plugins, cambios o actualizaciones antes de aplicarlos en producción.

No puedo esperar a que ocurra un fallo en el servidor para comprobar si puedo restaurarlo o no.

Las pruebas de restauración hasta ahora han terminado con algún tipo de problema y un sistema no funcional, donde se pierden imágenes u otros elementos.

Siguiendo esta saga:

https://meta.discourse.org/t/postgresql-12-update/151236/193

Probé el método de «copias de seguridad y restauración en otra instancia de Discourse» y ahora me enfrento a esto. He probado todos los trucos del oficio (el trabajo de Sidekiq, el rebake…), ¿hay alguna «pista» sobre qué podría estar causando esto? Solo para intentar averiguar algo.

(Una cosa que debo reconocerles: con todo esto, he pasado de «sí, más o menos entiendo esto» a tener un doctorado en PostgreSQL, un doctorado en Redis… :stuck_out_tongue: Solo necesito dominar Ruby y los entornos de desarrollo local, y quizás pueda ser útil para la comunidad :P)

¿Han desaparecido todos los avatares o solo algunos? Los avatares personalizados son básicamente Subidas. ¿Funcionan correctamente otras subidas?

Ve a la consola de Rails y verifica el registro del avatar no funcional en la base de datos. ¿Tienen la URL, el tamaño del archivo, el ancho, la altura y la extensión correctos?

User.find_by_username('Overgrow').user_avatar
User.find_by_username('Overgrow').uploaded_avatar

También deben tener sus versiones optimizadas presentes. Puedes verificarlo con:

OptimizedImage.where(upload_id: upload_id).where(version: 2)

En primer lugar, muchas gracias por tu ayuda @Overgrow.

Todos los avatares y emojis (e incluso las imágenes del sitio, como los encabezados, etc.) estaban “allí” pero invisibles. Para lo que no son avatares, aparecen como rotos; para los avatares, se muestra el marcador de posición gris. Algunas personas han podido simplemente subir uno nuevo y esos sí se ven.

En mis primeros intentos al ejecutar el comando obtuve:

FATAL:  the database system is in recovery mode

Así que… eso es todo :eyes: (tengo muchos “desconexiones”, así que asumo que tiene algo que ver con la base de datos, ¿quizás?)

Pero después de persistir eventualmente:

User.find_by_username(‘Overgrow’).user_avatar

=> #<UserAvatar:0x000055702722d200
 id: 4,
 user_id: 3,
 custom_upload_id: 20504,
 gravatar_upload_id: 12240,
 last_gravatar_download_attempt: Thu, 21 May 2020 10:16:55 UTC +00:00,
 created_at: Sat, 30 May 2019 16:33:16 UTC +00:00,
 updated_at: Thu, 21 May 2020 10:16:55 UTC +00:00>

(Intenté subir uno nuevo hoy, pero no funciona).

User.find_by_username(‘Overgrow’).uploaded_avatar

=> #<Upload:0x00005555cd911b58
 id: 20504,
 user_id: 3,
 original_filename: "16_2.png.jpg",
 filesize: 56220,
 width: 360,
 height: 360,
 url: "/uploads/default/original/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8.jpeg",
 created_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 updated_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 sha1: "63347a46c0ca945f53613722a73c233484d642c8",
 origin: nil,
 retain_hours: nil,
 extension: "jpeg",
 thumbnail_width: 360,
 thumbnail_height: 360,
 etag: nil,
 secure: false,
 access_control_post_id: nil,
 original_sha1: nil>

OptimizedImage.where(upload_id: 20504).where(version: 2)

=> [#<OptimizedImage:0x000056366a01c1a0
  id: 95962,
  sha1: "5a32b5cc3e6f5c58d88a3c92a23076980a8ce840",
  extension: ".jpeg",
  width: 200,
  height: 200,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg",
  filesize: 28916,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a0741e8
  id: 95942,
  sha1: "ee353c9e23511b471e1a59c1f71a2ded3e366b1e",
  extension: ".jpeg",
  width: 20,
  height: 20,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_20x20.jpeg",
  filesize: 1270,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074120
  id: 95943,
  sha1: "944fa9fc542a79a5c50394c75022bf84ace297e5",
  extension: ".jpeg",
  width: 30,
  height: 30,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_30x30.jpeg",
  filesize: 1952,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074058
  id: 95944,
  sha1: "983490e58bed58c971ffa44e440b02ce3ea72bba",
  extension: ".jpeg",
  width: 40,
  height: 40,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_40x40.jpeg",
  filesize: 2695,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a07bf60

Así que aparentemente las imágenes están allí, pero no se muestran. Solo aparece el marcador de posición gris del avatar predeterminado.

Todo parece correcto a nivel de registro de la base de datos. Puedes avanzar a niveles superiores cuando investigues.

¿Qué obtienes al seguir manualmente las URLs de las subidas que listaste?

¿Si añado /uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg (es decir) después de la URL de mi Discourse? Recibo un error 404, no encontrado.

Entonces… ¿no existen? (Lo pregunto con esperanza :P)

Comprueba también algunas URLs de archivos desde /uploads/default/original, no solo desde /uploads/default/optimized.

404 … Eso significa que debes verificar tu carpeta uploads dentro de /var/discourse/shared/standalone en el sistema de archivos y buscar dónde están los archivos antiguos reales (si existen). Cuando los encuentres, intenta comparar su ubicación con la de los archivos recién subidos (los que funcionan).

También puedes restaurarlos manualmente desde la copia de seguridad.

Gracias por la explicación.

Acabo de entrar, verifiqué dos veces y algunos de los caminos listados no existen.

Lo extraño es que tengo gente intentando subir archivos nuevos y esos tampoco funcionan. Cuando revisas con los comandos que me diste, puedes ver un camino que tampoco existe. ¿Cómo “mapea” Discourse esto? Porque una cosa que no termino de entender es que los archivos faltan (aunque se suponía que la copia de seguridad los incluiría), pero ¿cómo es posible que las nuevas subidas vayan a caminos fantasma?

Verifica la carpeta tombstone dentro de tu carpeta uploads: ¿están allí algunos de los archivos que faltan?

Lo único que veo dentro de uploads es la carpeta default… ¿la carpeta tombstone es para archivos obsoletos o algo así?

Además, un dato adicional: resulta que si un usuario intenta subir la misma imagen que ya tenía (incluso si cambia el nombre del archivo, supongo que, por lo que puedo ver en esas consultas, se basa en el hash), la imagen no se cargará y aparecerá vacía; una vez que guardes, verás el marcador de posición gris.

Aparentemente, si modificas la imagen de alguna manera (incluso si solo la guardas en un formato diferente en Photoshop), puedes volver a subirla.

Ese es un comportamiento normal. El hash del archivo de datos se almacena en la base de datos para evitar imágenes duplicadas.

¿Qué ocurre si subes una imagen a través del editor de redacción? ¿Se completa la subida? ¿Aparece en el panel de vista previa?

Si escribo un mensaje e incluyo una imagen, ¿se mostrará en el panel de vista previa y se completará la carga? Sí, es el comportamiento normal.

Entonces, ¿en qué punto exacto deja de mostrarse esa imagen?

Verifica la URL de la imagen que ves y rastrea su ubicación en el sistema de archivos.

Verifica la URL de las imágenes que no funcionan (usando las herramientas de desarrollador web en el navegador). ¿Cuál es la diferencia?

Quizás estén apuntando a un dominio diferente.

En el primer mensaje me refería específicamente a los avatares (a través del perfil del usuario), y el segundo es sobre el editor.

Así que, en un mensaje normal, si arrastras y sueltas una imagen o presionas el botón “subir imagen”, funcionará sin problemas, como es habitual.

En resumen:

  • Los avatares no se muestran, solo aparece el marcador de posición.
  • Los emojis personalizados tampoco se muestran.
  • Las imágenes del sitio (logotipo, etc.) tampoco se mostraban.
  • Si subes imágenes desde el editor, funciona correctamente.
  • Si intentas subir el mismo avatar que tenías antes del incidente, no funcionará. El comportamiento es el siguiente: se subirá, pero en el cuadro donde seleccionas si quieres una letra predeterminada, Gravatar o subir una imagen, se mostrará un cuadrado en blanco. Cuando confirmas tu elección y la página se recarga, verás el marcador de posición gris.

Además:

  • No hay ninguna carpeta “Tombstone”.
  • Las imágenes antiguas están en directorios (como se muestra en las consultas que me diste) que no existen.

Déjame revisar lo del dominio. Como nota, mientras buscaba información, probé lo siguiente:

  • Ejecutar el trabajo CreateMissingAvatars desde Sidekiq → Sin éxito.
  • Rebakear todas las publicaciones (sí, es un poco forzado) → Sin éxito.
  • Basándome en este hilo, como usé un dominio diferente (en realidad un subdominio) para probar la restauración desde una copia de seguridad mientras el sitio principal estaba offline, pensé que quizás algunas URLs podrían estar incorrectas, así que ejecuté esto: discourse remap talk.foo.com talk.bar.com → Sin éxito.

@Iceman

Esto es principalmente para tu información, y quizás sea demasiada información, pero podría ayudarte de alguna manera a obtener una visión adicional sobre algunas de las cosas interesantes que experimentamos al ejecutar tres contenedores (dos de aplicaciones web y uno de datos) al mismo tiempo (y cómo esto también afecta a los avatares de los usuarios).

Es muy interesante (y muy genial, en mi opinión) cómo funciona el programador de trabajos de Redis / Sidekiq cuando se ejecutan en paralelo, pero solo uno está “activo en el lado web del usuario”:

Espero que encuentres interesante esta breve discusión con un ejemplo del mundo real. Podría proporcionarte una pequeña cantidad de información sobre el programador de trabajos de Discourse, la optimización de imágenes y los avatares según nuestra configuración:

Soy un gran admirador de cómo Discourse utiliza Redis / Sidekiq para programar trabajos en segundo plano; y considero que esta es una de las fortalezas y beneficios clave de la arquitectura del software de Discourse.

Nota: Estos conceptos también se aplican, de diversas maneras sutiles, a diferentes etapas del proceso de respaldo y restauración y otros procesos (dependientes del tiempo), por lo que es una buena idea entender cómo y por qué Sidekiq programa trabajos en segundo plano.

¡Gracias por la información, @neounix! Es muy útil para entender mejor los “entresijos” de Discourse desde la perspectiva de “estoy aprendiendo Rails para poder ayudar, pero, ¡por Dios!, la curva de aprendizaje es empinada mientras intentas solucionar tu propia instalación” :stuck_out_tongue:

Ahora me estoy centrando en Redis/Sidekiq para intentar entender por qué algunos incrustados no funcionan, ya que creo que podría estar relacionado con “Bake”, pero no puedo asegurarlo todavía porque aún estoy en proceso de depuración (espero).

En cuanto a mi problema aquí, gracias a @Overgrow pude determinar lo siguiente:

  • De hecho, el proceso de copia de seguridad copió los archivos en la copia de seguridad, pero no los restauró en la instalación de Discourse. Según el estado y/o las correcciones de mis otros tres problemas, podría necesitar recuperar otra copia de seguridad en otra instalación y volver a probar el proceso de copia de seguridad, pero podría ser un problema para todos; aún no lo sé.

  • Debido a eso, ocurría ese comportamiento extraño.

  • Terminé abriendo la copia de seguridad e inyectando los archivos faltantes en la instalación. Todo se recuperó sin necesidad de volver a “Bake”.

Sin embargo, los otros problemas persisten (no poder reconstruir el contenedor de datos, sobre lo cual no tengo ni idea, y dos problemas que me están llevando a centrarme en Sidekiq y los eventos, porque podrían resolverse así: algunos Oneboxes (específicamente de YouTube) no funcionan y algunas notificaciones sobre “falsas” ediciones que ocurren recursivamente en algunos usuarios, aunque no se haya realizado ninguna edición. Así que creo que la nueva instalación podría tener problemas con sus eventos; estoy intentando averiguarlo. :man_shrugging: