Avatares perdidos após restauração. Como recuperá-los?

Bom dia @ariznaf,

Antes de chegar a essa conclusão, você poderia acessar todas as suas instalações, entrar na pasta compartilhada de cada uma delas e executar o seguinte comando em cada instalação, postando os resultados aqui?

# du -sh uploads

Por exemplo, nas nossas instalações, fiz o seguinte:

Instalação Original:

# du -sh uploads
2.5G uploads

Instalação Apenas Socket (antes de corrigir o problema):

# du -sh uploads
444K uploads

Isso me deu a pista necessária para perceber que precisava copiar manualmente a pasta uploads; e, conhecendo o problema, a solução é simples.

Se você verificar todas as suas diferentes pastas uploads com du -sh uploads em todos os diretórios compartilhados, isso fornecerá uma pista valiosa sobre o que está acontecendo.

Se forem diferentes, então você saberá que algumas uploads estão faltando e poderá corrigir manualmente.

Se forem todas iguais (improvável), então o problema se torna mais interessante :slight_smile:

Encontrei o problema (não a solução).
O problema não está na restauração em si, mas na mudança do nome do servidor.

Deixe-me explicar como fiz a restauração (caso haja alguma etapa faltando).

Baixei uma cópia fresca do Discourse do GitHub.
Executei o processo de configuração do Docker.
Antes de iniciar o aplicativo e prosseguir com a restauração, editei o app.yml para configurar o acesso ao socket.
E alterei o nome do host para b.domain.com (no original era a.domain.com).

Configurei o proxy reverso nginx usando SSL para direcionar o tráfego HTTPS na porta 443 para o socket do Discourse.
Em seguida, reconstruí (launcher rebuild app) e reiniciei o nginx (service nginx restart).
Acessei https://b.domain.com para fazer a configuração inicial do Discourse.
Configurei para restaurar a partir do S3 e restaurei o último backup feito do banco de dados e dos uploads (sem miniaturas).
Após a restauração, você é desconectado.
Editei o app.yml para copiar o app.yml do site antigo (a fim de obter a mesma configuração e os mesmos plugins).
Mudei o nome do host para b.domain.com no app.yml.

Novamente, uma reconstrução e reinício do nginx.

O PROBLEMA persiste: as imagens de perfil (miniaturas) de todos que alteraram seu perfil foram substituídas pela imagem de perfil branca.
Nosso logotipo no canto superior esquerdo também está ausente.

@Stephen: o force_https estava ativado (como estava no servidor original, sem problemas). Tive ativar e desativar, sem efeito. Deixei-o ativado, pois queremos que nosso site seja acessado via HTTPS (de qualquer forma, o tráfego http:80 tem um redirecionamento permanente na nossa configuração do nginx para https:443).

@riking: usei o Sidekiq e acionei o job avatarmissing, que parece ter terminado corretamente em alguns milissegundos. Apenas para garantir que não fosse um processo demorado, esperei quase 24 horas para ver se as imagens de perfil seriam reconstruídas.
Mas hoje temos o mesmo problema: sem imagens de avatar (para pessoas que fazem upload de uma imagem de perfil) e sem imagem do logotipo.

Depois disso, tentei ver se o problema era a mudança de nome, como sugerido por @Stephen.

Mudei de volta o nome do host no app.yml e no nginx para a.domain.com (o original) e reconstruí e reiniciei o nginx.
Editei meu arquivo local de hosts para apontar a.domain.com para o IP do novo servidor e fiz um ping para confirmar que estava acessando o novo IP.

E VOA! Lá estavam os avatares e nosso perfil.

Portanto, o problema não está na restauração em si; o problema é que, de alguma forma, o caminho completo da URL é salvo e o sistema tenta acessá-lo do local errado.
É estranho, de qualquer forma, já que o servidor original está ativo e em execução (deveria ter encontrado as imagens mesmo do local errado, o servidor original em vez do novo).

Mas, de qualquer forma, o problema não está no processo de restauração ou na necessidade de reenviar as imagens devido a algum tipo de corrupção.

O problema é a mudança no nome do servidor.

Agora, a pergunta é: como migrar um fórum Discourse de um domínio/nome de host para outro?

Tentei novamente alterar o nome do host para b.domain.com.

Sem sucesso.

Parece que, ao usar o nome antigo, tudo funciona (mas agora suspeito que ele está carregando imagens e outros conteúdos do servidor antigo, que ainda está online, pois recebo novas postagens e notificações de postagens recentes no servidor antigo, mesmo tendo alterado o IP de a.domain.com no meu arquivo hosts).

Segui as instruções deste tópico para alterar o nome do host:

Achei que fazer o Discourse remapear a.domain.com para b.domain.com resolveria o problema.
Até executei o rake posts:rebake, mas o resultado foi o mesmo.

Perdi os avatares e o logotipo, e as imagens inseridas nas postagens também sumiram.

Por fim, como sugerido por @neounix, extraí novamente todos os uploads para substituir o destino em shared/standalone/uploads/, mas sem sucesso; os resultados continuam os mesmos.

Há realmente alguma informação valiosa no seu banco de dados? Pode ser mais fácil simplesmente começar do zero, sem se preocupar com migrações de servidor.

Todos os dados e posts desde o início do fórum, há meses?

Como já disse, consegui mover o servidor para outro, parando o servidor, copiando todos os dados para um novo e reiniciando-o.

Mas o suporte me informou que a maneira correta de fazer isso é usando o backup padrão e restaurando o banco de dados.

Estou tentando fazer isso, mas toda vez surge algum tipo de problema.
Preciso também de um servidor para testes, a fim de verificar os efeitos de plugins, alterações ou atualizações antes de aplicá-los em produção.

Não posso esperar até que ocorra uma falha no servidor para ver se consigo restaurá-lo ou não.

Os testes de restauração até agora terminaram com algum tipo de problema, deixando o sistema não funcional, com perda de imagens ou outros elementos.

Seguindo essa saga:

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

Tentei o método de “backup e restauração em outra instância do Discourse” e agora estou enfrentando isso. Experimentei todos os truques do livro (o Job do Sidekiq, o Rebake)… há alguma “pista” sobre o que pode estar causando isso? Apenas para eu tentar descobrir algo.

(Uma coisa que tenho que reconhecer: com tudo isso, estou evoluindo de “sim, eu meio que entendo isso” para PhD em PostgreSQL, PhD em Redis… :stuck_out_tongue: Só preciso me familiarizar com Ruby e ambientes de desenvolvimento local, e posso me tornar útil para a Comunidade :stuck_out_tongue: )

Todos os avatares desapareceram ou apenas parte deles? Avatares personalizados são basicamente Uploads. Outros uploads funcionam conforme o esperado?

Vá ao console do Rails e verifique o registro do avatar não funcional no banco de dados. Eles possuem as informações corretas de URL, filesize, width, height e extension?

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

Eles também precisam ter suas versões otimizadas presentes. Você pode verificar isso com:

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

Primeiramente, muito obrigado pela sua ajuda @Overgrow.

Todos os avatares e emojis (e até mesmo as imagens do site, como cabeçalhos, etc.) estavam “lá”, mas invisíveis. Para itens que não são avatares, eles aparecem como quebrados; para avatares, aparece o marcador de posição cinza. Algumas pessoas conseguiram apenas fazer o upload de um novo e esses você consegue ver.

Nas primeiras tentativas de executar o comando, obtive:

FATAL: o sistema de banco de dados está em modo de recuperação

Então… é isso :eyes: (tenho muitos “desconexões”, então estou assumindo que tem algo a ver com o banco de dados, talvez?)

Mas, após 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>

(Tentei fazer o upload de um novo hoje, mas não funcionou).

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

Então aparentemente as imagens estão lá, mas não são exibidas. Apenas o marcador de posição cinza do avatar padrão aparece.

Tudo parece estar correto no nível do registro do banco de dados. Você pode avançar para níveis superiores ao investigar.

O que você obtém ao seguir manualmente os URLs dos uploads que você listou?

Se eu colocar /uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg (ou seja) após a URL do meu Discourse, recebo um erro 404, não encontrado.

Então… eles não existem? (Estou perguntando com esperança :P)

Verifique também algumas URLs de arquivos em /uploads/default/original, não apenas em /uploads/default/optimized.

404 … Isso significa que você precisa verificar a pasta uploads dentro de /var/discourse/shared/standalone no sistema de arquivos e localizar onde estão os arquivos antigos reais (se existirem). Quando os encontrar, tente comparar a localização com os arquivos recém-enviados (aqueles que funcionam).

Você também pode restaurá-los manualmente a partir do backup.

Obrigado pela explicação.

Apenas entrei lá, verifiquei novamente e alguns dos caminhos listados não existem.

A parte estranha é que tenho pessoas tentando fazer upload de novos arquivos e esses novos também não funcionam. Quando você verifica com os comandos que me deu, é possível ver um caminho que também não existe. Como o Discourse “mapeia” isso? Porque uma coisa que não consigo entender é que os arquivos estão faltando (embora o backup devesse tê-los transferido), mas novos uploads indo para caminhos fantasma?

Verifique a pasta tombstone dentro da pasta uploads - alguns dos arquivos ausentes estão lá?

A única pasta que vejo dentro de uploads é default… a pasta tombstone é para arquivos obsoletos ou algo assim?

Além disso, uma informação extra: descobri que, se um usuário tentar fazer o upload da mesma imagem que já possui (mesmo que altere o nome do arquivo; suponho que, pelo que vejo nessas consultas, a verificação seja baseada no hash), a imagem não será carregada e aparecerá vazia. Ao salvar, você verá o marcador cinza.

Parece que, se você modificar a imagem de alguma forma (mesmo que apenas salvando-a em um formato diferente no Photoshop), poderá fazer o upload novamente.

Isso é um comportamento normal. O hash do arquivo de dados é armazenado no banco de dados para evitar imagens duplicadas.

O que acontece quando você faz o upload de uma imagem através do editor de composição? O upload é concluído? A imagem aparece no painel de visualização?

Se eu escrever uma mensagem e incluir uma imagem nela? Ela aparecerá no painel de pré-visualização e o upload será concluído, sim, comportamento normal.

Então, em qual ponto exato essa imagem deixa de aparecer?

Verifique a URL dessa imagem que você vê e rastreie-a até o sistema de arquivos.

Verifique a URL das imagens que não funcionam (por meio das ferramentas de desenvolvedor do navegador). Qual é a diferença?

Talvez elas estejam apontando para domínios diferentes.

Na primeira mensagem, eu me referi especificamente aos avatares (através do perfil do usuário), e na segunda, ao editor.

Então, em uma mensagem normal, se você arrastar e soltar ou clicar no botão “carregar imagem”, funcionará perfeitamente, como de costume.

Em resumo:

  • Os avatares não são exibidos, apenas o espaço reservado.
  • Emojis personalizados também não aparecem.
  • Imagens do site (logotipo, etc.) também não estavam sendo exibidas.
  • Se você fizer upload de imagens no editor, funciona normalmente.
  • Se tentar fazer upload do mesmo avatar que você tinha antes do incidente, não funcionará. O comportamento é o seguinte: o upload será realizado, mas na caixa onde você seleciona se deseja uma letra padrão, Gravatar ou upload, será exibido um quadrado em branco. Quando você confirmar sua escolha e a página for recarregada, você verá o espaço reservado cinza.

Além disso:

  • Não há pasta Tombstone.
  • As imagens antigas estão em diretórios (como mostrado nas consultas que você forneceu) que não existem.

Vou verificar a questão do domínio. Como observação, quando estava buscando informações, tentei:

  • Acionar o job CreateMissingAvatars no Sidekiq → Sem sucesso.
  • Recriar todos os posts (sim, um pouco forçado) → Sem sucesso.
  • Com base nesta discussão, como usei um domínio diferente (na verdade um subdomínio) para testar a restauração a partir de backup enquanto o site principal estava offline, pensei que talvez algumas URLs estivessem incorretas, então executei: discourse remap talk.foo.com talk.bar.com → Sem sucesso.

@Iceman

Isso é principalmente para seu conhecimento e talvez seja demais, mas pode ajudá-lo de alguma forma a obter insights adicionais sobre algumas das coisas interessantes que experimentamos ao executar três contêineres simultaneamente (dois de aplicação web e um de dados) (e como isso também afeta os avatares dos usuários).

É muito interessante (e muito legal, na minha opinião) como o agendador de jobs do Redis/Sidekiq funciona quando eles estão rodando em paralelo, mas apenas um está “ativo no lado da web do usuário”:

Espero que você ache interessante essa breve discussão com um exemplo do mundo real. Ela pode fornecer uma pequena quantidade de insights sobre o agendador de jobs do Discourse, otimização de imagens e avatares com base na nossa configuração:

Sou um grande fã de como o Discourse usa o Redis/Sidekiq para agendar jobs em segundo plano; e considero isso uma das principais forças e benefícios da arquitetura de software do Discourse.

Nota: Esses conceitos também se aplicam, de várias maneiras sutis, a diferentes etapas do processo de backup e restauração e outros processos (dependentes de tempo), então é uma boa ideia entender como e por que o Sidekiq agenda jobs em segundo plano.

Obrigado pelas informações, @neounix. Elas são muito úteis para entender melhor os “bastidores” do Discourse, especialmente na perspectiva de quem está aprendendo Rails para poder ajudar, mas, por Deus, a curva de aprendizado tem sido íngreme enquanto tento corrigir minha própria instalação :stuck_out_tongue:

No momento, estou focado no Redis/Sidekiq para tentar entender por que alguns embeds não estão funcionando, já que acho que isso pode estar relacionado ao “Bake”, mas não posso afirmar com certeza, pois ainda estou avançando na parte de depuração (espero).

Sobre o meu problema aqui, graças ao @Overgrow, consegui determinar que:

  • De fato, o Processo de Backup copiou os arquivos para o backup, mas não os restaurou na instalação do Discourse. Com base no status e/ou nas correções dos meus outros três problemas, talvez eu precise recuperar outro backup em outra instalação e testar novamente o processo de backup, mas pode ser um problema para todos; ainda não sei.

  • Por causa disso, o comportamento estranho estava ocorrendo.

  • Acabei abrindo o backup e injetando os arquivos faltantes na instalação. Tudo foi recuperado sem a necessidade de um novo Bake.

No entanto, os outros problemas persistem: não consigo reconstruir o container de Dados, sobre o qual estou totalmente perdido, e mais dois problemas que estão me fazendo focar no Sidekiq e nos eventos, pois podem ser resolvidos dessa forma: alguns Oneboxes (especificamente do YouTube) não estão funcionando e há notificações sobre edições “falsas” ocorrendo recursivamente para alguns usuários, mesmo que nenhuma edição tenha acontecido. Acredito que a nova instalação pode ter problemas relacionados aos eventos e estou tentando descobrir o que está acontecendo. :man_shrugging: