A versão do Discourse que você está executando inclui uma versão do aws-sdk-s3 que deve fornecer Aws::S3::TransferManager.
Você está usando a instalação oficial do Discourse via Docker? Se estiver usando o setup oficial do Docker, o contêiner foi totalmente recriado como parte da atualização?
Sim, acredito que estou usando a instalação oficial do Discourse via Docker. Existe alguma forma de eu ter certeza disso? Já faz um tempo desde que realizei a instalação.
Para atualizar, executei ./launcher rebuild app. Suponho que isso signifique que o container foi totalmente recriado, mas talvez eu esteja errado?
Alguns detalhes adicionais que podem ser relevantes:
Estou usando Ubuntu 24.04.4 LTS
O app.yml instala os plugins oficiais docker_manager e discourse-doc-categories no hook after_code. Não há outros plugins definidos no app.yml.
Estou tentando armazenar os backups em um armazenamento compatível com S3 fornecido pela Backblaze, e isso funcionava anteriormente.
Uma coisa que pode ajudar a estreitar a busca é verificar qual gem aws-sdk-s3 está sendo carregada de fato dentro do container em execução.
A alteração no Discourse que introduziu o Aws::S3::TransferManager também atualizou o aws-sdk-s3 da versão 1.182.0 para a 1.227.0:
Na revisão do Discourse que você vinculou, o Gemfile.lock ainda deve estar usando o aws-sdk-s3 1.227.0, que fornece o Aws::S3::TransferManager.
Você poderia tentar entrar no container:
cd /var/discourse
./launcher enter app
Em seguida, dentro do container:
cd /var/www/discourse
bundle info aws-sdk-s3
bundle exec ruby -e '
require "aws-sdk-s3"
puts "gem: #{Gem.loaded_specs["aws-sdk-s3"]&.full_name}"
puts "path: #{Gem.loaded_specs["aws-sdk-s3"]&.full_gem_path}"
p Aws::S3.autoload?(:TransferManager)
p Aws::S3::TransferManager
'
Também pode ser útil verificar a própria aplicação sob o Rails:
RAILS_ENV=production bundle exec rails runner '
puts "aws-sdk-s3: #{Gem.loaded_specs["aws-sdk-s3"]&.version}"
p Aws::S3.autoload?(:TransferManager)
p Aws::S3::TransferManager
'
Depois, saia do container com:
logout
Se isso reportar uma versão mais antiga do aws-sdk-s3, ou se o TransferManager estiver ausente, isso explicaria a exceção no backup e sugeriria que as gems instaladas no container não correspondem ao Gemfile.lock atual do Discourse.
Se reportar a versão 1.227.0 e resolver o Aws::S3::TransferManager com sucesso, então o problema é mais incomum e saberemos para onde olhar: o que difere entre o processo de backup do Sidekiq e aquele ambiente interativo.
Como você está usando ./launcher rebuild app, isso soa como o fluxo padrão do discourse_docker; os comandos acima devem nos dizer com mais precisão o que acabou ficando no container reconstruído.
Ao investigar isso, lembrei que eu usava este workaround para contornar um problema em que o AWS SDK não funcionava com o Backblaze. Ao me atualizar sobre o tópico, vi que o Backblaze atualizou sua API, o que torna o workaround desnecessário.
Depois que removi o workaround, o backup foi concluído com sucesso! Obrigado pela ajuda.
Uma reflexão a partir disso: modelos de compatibilidade temporários como este podem ser mais seguros se tiverem algum tipo de condição de autoexpiração/guarda, em vez de continuar sobrescrevendo as dependências do Discourse indefinidamente.
Por exemplo, com backports temporários de código-fonte, estou planejando usar hooks em produção que primeiro verifiquem se a correção upstream já está presente e apliquem o patch apenas se ainda for necessário.
Neste caso, algo ao longo dessas linhas poderia potencialmente ter impedido que o pin antigo aws-sdk-s3 1.177.0 continuasse uma vez que o próprio Discourse começou a depender de funcionalidades mais novas do SDK:
hooks:
after_bundle_exec:
- exec:
cd: $home
cmd:
- |
if grep -q "Aws::S3::TransferManager" lib/s3_helper.rb; then
echo "Discourse agora requer Aws::S3::TransferManager; pulando o downgrade obsoleto do aws-sdk-s3 do Backblaze"
else
echo "Aplicando pin temporário de compatibilidade do aws-sdk-s3 do Backblaze"
bundle config set frozen false
sed -i 's/gem "aws-sdk-s3", require: false/gem "aws-sdk-s3", "1.177.0", require: false/' Gemfile
bundle update aws-sdk-s3
bundle add aws-sdk-core --version 3.215
fi
Essa verificação específica é apenas ilustrativa - uma verificação de versão mais geral ou uma falha explícita quando o Discourse passar da versão de SDK esperada provavelmente seria melhor.
Mesmo falhar de forma explícita seria provavelmente preferível a silenciosamente produzir um container cujos gems não correspondem mais às versões esperadas pelo Discourse.
Embora eu concorde que falhar de forma explícita teria sido desejável, o caso era que, anteriormente, eu queria que as gems não corresendessem às versões esperadas pelo Discourse, porque a versão mais recente do aws-sdk-s3 enviava cabeçalhos que o Backblaze não suportava e eu queria que os backups funcionassem.
Não sei se havia alguma verificação que eu poderia ter configurado proativamente para me notificar quando o contorno (workaround) deixasse de ser necessário. Implementei o contorno há um ano e meio, em abril de 2025, antes que uma correção estivesse disponível.
Acho que o melhor que eu poderia ter feito foi adicionar uma data de expiração, para me forçar a verificar se o contorno ainda era necessário. Uma funcionalidade assim seria bem-vinda. Ou talvez a responsabilidade seja minha de ser mais proativo e configurar lembretes para verificar se o contorno ainda é necessário. Ter algumas anotações me ajudou nesse aspecto.