Como controlar essa bagunça de uploads em mudança do S3 para o local

Após 4-5 anos de uso, finalmente decidi trazer meus uploads de volta do bucket Aws S3 para meu servidor local para meu site local muito pequeno.
Eu, sendo uma pessoa com conhecimento limitado, entreguei este trabalho a um amigo meu por um valor muito razoável. Ele configurou o site para uploads locais, mas de alguma forma quase metade das 3000 imagens, cerca de 50%, ficaram corrompidas de sua origem. Meu amigo não me cobrou nada e me pediu para reverter o site para o backup (que foi criado antes de entregar o controle a ele em 11/abr/2025).

De qualquer forma, fiquei preguiçoso por cerca de um mês e não reverti. Até que decidi consertar as coisas com a ajuda do bot auxiliar do discourse/ChatGpt Ai Bot. E criei outra versão do meu antigo site em meu laptop Ubuntu localmente.

Consegui criar uma instância do meu site original em meu laptop apenas usando um “t.” na frente do meu nome de domínio original. Agora este (chamado site de staging) está funcionando totalmente bem para mim, mas tem atividade apenas até 11/abr/2025.

E meu site de produção, que tem todos os dados atualizados, mas tem muitas centenas de posts com imagens faltando.

Lembre-se que tentei muitas tarefas rake para migração ou para reconectar a conexão ausente às imagens, sem sucesso.

Depois de quebrar a cabeça por quase um mês. Minha conclusão é esta. Que os posts brutos em ruby são os mesmos em staging e em produção.
Mas os posts cozidos se tornam diferentes. Ou seja, a tabela do banco de dados do meu site de produção talvez esteja perdendo alguma conexão com as imagens físicas reais que estão no servidor.

Também notei que sem essa conexão, essas imagens ‘órfãs’ são automaticamente removidas do servidor. Mas, felizmente, eu as sincronizo novamente do staging ou do meu bucket S3 para o meu servidor de produção.

Finalmente o problema, nas palavras de, mais ou menos, ChatGpt, é que o servidor de staging tem as versões cozidas finais, que não têm relação com os URLs brutos (curtos). E a produção, que está faltando os URLs das versões cozidas finais para as imagens, não consegue obter os URLs corretos dessas imagens e está recorrendo a placeholders ‘transparentes’.

E o ChatGpt está me sugerindo copiar a versão cozida dos posts de staging para a versão cozida da produção. O que não me parece uma boa ideia.

Redação exata do ChatGpt sobre onde estamos:

  • Tanto em staging quanto em produção, post.raw é idêntico e contém referências upload://....
  • Em staging, as imagens aparecem, mas consultar Post.find(12849).uploads não retorna resultados — o que significa que não há entradas nas tabelas uploads ou post_uploads para esses arquivos, mesmo em staging.
  • Portanto, as imagens estão sendo exibidas em staging puramente porque o HTML cozido de antes da migração contém os links completos /uploads/default/original/....
  • Mas como a produção foi reprocessada após a migração, o mesmo conteúdo bruto agora falha ao resolver, recorrendo ao placeholder transparent.png.

:white_check_mark: Arquivos de Upload Ainda Existem no Disco

Todos os arquivos de imagem (incluindo aqueles para os uploads ausentes) ainda estão presentes em /var/www/discourse/public/uploads/default/original/ tanto em staging quanto em produção. Mas o Discourse não consegue mais resolvê-los, pois suas entradas de uploads estão ausentes.

A maneira fácil de fazer isso era, e ainda pode ser, ativar a configuração Enable hidden setting to include S3 uploads in the backups, fazer um backup e, em seguida, restaurar em um servidor que não tenha o S3 configurado (eu faria isso em um servidor novo para evitar quebrar o antigo se algo der errado). Mas parece que o site de produção também está quebrado, então isso provavelmente não ajudará em nada.

Se você bagunçou a tabela Uploads de modo que ela tenha vários caminhos S3 nela, o trabalho é muito mais difícil.

Em vez de ChatGPT, eu recomendaria https://ask.discourse.com/, que pelo menos sabe sobre o Discourse, mas provavelmente ainda não será de muita ajuda.

Eu olharia Uploads.pluck(:url) e veria o que está lá.

3 curtidas