Avatares demoram muito para carregar após a migração para o R2 compatível com S3

Olá,

Acabei de migrar para o R2 e tudo ocorreu perfeitamente. Todas as imagens têm o link de URL do CDN S3. No entanto, percebi um problema: os avatares estão demorando muito para carregar. Em média, leva cerca de 3 a 4 segundos, seja clicando no avatar de um usuário ou visualizando dentro de uma publicação. Isso é esperado?

hmmm, suspeito que possa ser um de 3 problemas diferentes, mas o mais provável para mim é o redimensionamento em tempo real.

1. Redimensionamento de avatar em tempo real

quando você migrou seus uploads para o R2, ele moveu as imagens originais; no entanto, o Discourse usa vários tamanhos diferentes de avatares (por exemplo, 45px para posts, 120px para o cartão do usuário).

se esses tamanhos otimizados específicos não foram migrados perfeitamente, ou ainda não foram gerados, o Discourse precisa gerá-los de forma síncrona no momento em que o usuário clica neles:

  1. o Discourse baixa o avatar original do R2 para o servidor local
  2. redimensiona-o usando o ImageMagick
  3. faz upload do novo tamanho de volta para o R2
  4. redireciona o navegador para a nova URL, e esse processo leva de 3 a 4 segundos

para verificar: atualize forçadamente a página — se o avatar demorar 3-4 segundos na primeira vez, mas carregar instantaneamente na segunda vez, é exatamente isso que está acontecendo.

para corrigir: isso se corrigirá naturalmente à medida que os usuários navegarem e os tamanhos forem gerados. Mas você pode corrigi-lo instantaneamente, forçando o servidor a pré-gerar todos os avatares em segundo plano, acessando seu servidor via SSH e executando:

./launcher enter app
rake avatars:refresh

2. O tempo limite de 3 segundos do IPv6

se os avatares estiverem demorando 3-4 segundos todas as vezes, mesmo após várias atualizações, eles provavelmente estão atingindo um tempo limite de rede.

os endpoints da API do Cloudflare R2 são dual-stack, ou seja, usam tanto IPv4 quanto IPv6. Se a sua droplet de servidor tiver um endereço IPv6 atribuído a ela, mas o gateway IPv6 do host não estiver roteado corretamente, a conexão interna do Ruby com o bucket do R2 tentará usar o IPv6 primeiro, ficará pendurada por 3 segundos (este é o tempo limite padrão do TCP do Linux), falhará e então bem-sucedida instantaneamente usando o IPv4.

para verificar: acesse o servidor via SSH e execute:

curl -I -6 https://cloudflare.com

se ele ficar pendurado por alguns segundos e falhar, o IPv6 do servidor está quebrado, fazendo com que cada verificação interna da API S3 sofra um atraso de 3 segundos.

para corrigir: você precisará corrigir o roteamento IPv6 no painel de controle do seu host ou talvez até desativar o IPv6 na droplet completamente.

3. Atrasos do Gravatar

se o seu site estiver configurado para verificar atualizações do Gravatar, ele pode estar fazendo ping nos servidores externos do Gravatar antes de renderizar o avatar. Se o servidor tiver uma conexão de saída lenta (também frequentemente relacionada a DNS ou IPv6), é provável que isso bloqueie a renderização do avatar.

para verificar: execute isso no seu servidor
curl -I -6 https://gravatar.com
se ele ficar pendurado por 3 segundos, o IPv6 está quebrado (veja acima)

correção relacionada ao Gravatar: nas configurações do seu Discourse, vá para baixar gravatars automaticamente, desative-o temporariamente e veja se isso corrige o problema — não acho que este seja o problema, mas se for, você pode deixar a configuração desativada, ou corrigir o roteamento IPv6 como no item 2 acima, ou talvez alterar o resolvedor DNS.

Obrigado pela sua rápida resposta. Acredito que já tenha tentado o ‘rake avatars:refresh’ antes, mas não tenho certeza absoluta.

O que costumava funcionar para mim para ver o avatar abrir imediatamente era clicar nele pela primeira vez; na segunda vez, ele abria instantaneamente. Mas isso provavelmente se deve ao cache. Também acabei de testar sua segunda dica e ela retornou um “HTTP/2 301”, com várias outras linhas. O mesmo aconteceu com a dica 3. Vou executar o avatars:refresh novamente em alguns dias, pois precisei restaurar um snapshot. Mais uma vez, obrigado!

Gravatar

server: nginx
date: Mon, 22 Jun 2026 19:29:00 GMT
content-type: text/html; charset=utf-8
content-length: 0
content-language: en
expires: Wed, 11 Jan 1984 05:00:00 GMT
cache-control: no-cache, must-revalidate, max-age=0
x-redirect-by: Gravatar
location: https://en.gravatar.com/
alt-svc: h3=":443"; ma=86400
strict-transport-security: max-age=31536000; includeSubdomains; preload

CF

HTTP/2 301
date: Mon, 22 Jun 2026 19:27:00 GMT
content-type: text/html
content-length: 167
location: https://www.cloudflare.com/
cache-control: max-age=3600
expires: Mon, 22 Jun 2026 20:26:59 GMT
set-cookie: __cf_bm=eBP2aJ7Eg30nHPuvMMNxxKrgNtcNwKs0WDgnYyONeus-1782156420-1.0.1.1-sXpW27iuhGDF615cOfwNFybH4IMxgvZy3uA_3X_o..402T_3KSgT7CSymipL5RjdpGe3raWEqsVxQFFLPKRoDjfoT7B.0rqyDt.osbkOF98; path=/; expires=Mon, 22-Jun-26 19:57:00 GMT; domain=.cloudflare.com; HttpOnly; Secure; SameSite=None
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=QfYqSekEDPJHC2k%2BMjHN0cGjz172tmUWe2GSR8EgwNLh3TGjFYkQ0vwPxlzY1NcBcKFOMaAi4FlgjqjhETOOtHf%2BH9KdQSvqN3OME2Uh1i4nHIw%2Fy1qkvSpf4jxDchM7CaDW80tJkjBV4OqF"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
strict-transport-security: max-age=15780000; includeSubDomains
server: cloudflare
cf-ray: a0fda5d8ecd6b26d-LAX
alt-svc: h3=":443"; ma=86400

Sim, dada a sua resposta, estou quase certo de que se trata do problema #1, porque os resultados do comando curl para o Cloudflare e o Gravatar parecem estar conforme o esperado. Tente executar rake avatars:refresh quando for conveniente para você e me avise se funcionar.

E aí, Lilly, ainda estou tendo o mesmo problema. Mesmo depois de rodar o rake avatars:refresh. O problema também aparece na rota /latest. Testei limpando o cache do meu navegador e do Cloudflare, mas sem sucesso até agora. Será que preciso esperar um pouco? Estou testando isso em um fórum com 4500 usuários.

não limpe mais o cache do seu navegador ou do Cloudflare. quando você executa rake avatars:refresh para tantos usuários, isso não acontece instantaneamente. em vez disso, ele envia milhares de jobs para o Sidekiq processarem em segundo plano, o que pode levar várias horas, dependendo da CPU do seu servidor. desculpe por isso, eu deveria ter mencionado o Sidekiq e que isso pode demorar um pouco, dependendo de quantos usuários houver.

vá para your-forum.com/sidekiq/queues e observe a fila. espere até que ela fique completamente vazia. assim que o Sidekiq terminar, todos os tamanhos devem estar permanentemente no seu bucket R2, e acho que o carregamento dos seus avatares deve voltar à velocidade normal.

Ok, acho que está acontecendo outra coisa. Não tenho nada nas minhas filas. Mas se eu clicar no avatar de qualquer usuário, isso aparece em ‘tail -f log/production.log’: Sent file /var/www/discourse/tmp/avatar_proxy/3689d91eb5e1013beef831c585b5e62edeeecbd6.jpeg (0.2ms)

Uau, ok. Isso provavelmente é a prova definitiva e aponta para um problema diferente.

avatar_proxy nos logs geralmente significa que o Discourse está se recusando a servir o avatar diretamente da CDN R2 do Cloudflare. Em vez disso, o Discourse está interceptando agressivamente a solicitação e baixando a imagem do R2 para a pasta /tmp do servidor local, e então usando Ruby para servir a imagem ao navegador. Então, acho que isso está contornando completamente a CDN e explica o atraso de 3 segundos — suspeito que o servidor esteja buscando e carregando o arquivo manualmente em cada solicitação :grimacing:

O Discourse usa o avatar_proxy em alguns cenários muito específicos e, geralmente, é uma configuração de privacidade ou segurança que força o servidor a mascarar a URL externa.

Verifique essas configurações em Admin - Configurações do site:

Encontre external system avatars url — se houver algo nessa caixa (como /letter_avatar_proxy/v4/...), exclua para deixá-la vazia. Isso deve impedir que o Discourse faça proxy dos avatares de letra padrão. Também vale a pena verificar uploaded avatars allowed groups e garantir que esteja definido como TL_0.

Talvez verifique novamente DISCOURSE_S3_CDN_URL para garantir que esteja correto, sem barra no final ou erro de digitação?

Remapear avatares personalizados:
Parece provável que seu banco de dados ainda contenha as URLs brutas do bucket R2 em vez da sua nova URL de CDN; como elas não coincidem, seu fórum provavelmente está fazendo proxy delas por motivos de segurança.

Verifique no console do Rails para ver exatamente com o que o Discourse está lutando:

./launcher enter app
rails c

Escolha um usuário com um avatar de carregamento lento

u = User.find_by_username("o_usuario_escolhido")
u.user_avatar.custom_upload.url

Se a saída retornar uma URL de bucket bruta, seus remapeamentos anteriores não capturaram tudo (talvez tenha perdido um subdomínio ou um esquema).

Para corrigir, faça SSH no seu servidor, volte para o seu container novamente (não o Rails) (./launcher enter app) e execute a ferramenta de remapeamento (de novo, rs) para trocar a URL bruta pela sua URL de CDN:

discourse remap "https://<sua-url-bruta-cloudflare>.r2.cloudflarestorage.com" "https://cdn.seu-dominio.com"

Em seguida, execute novamente usando // em vez de https://, só para garantir.

A propósito, por curiosidade, qual serviço de hospedagem você está usando? Tenho a mesma configuração geral que você e ainda não experimentei esse problema. Então, também estou interessado na sua configuração e quero tentar reproduzi-la de alguma forma.

a URL que obtenho mostra a URL do CDN da S3, e consigo abrir a imagem no navegador.

Vou deixar a S3 de lado por enquanto, pois realmente não preciso dela neste momento.

e eu uso o Advinservers há muito tempo.

obrigado pela ajuda, muito apreciado