Les avatars mettent du temps à se charger après le passage à R2 compatible S3

Bonjour,

Je viens de migrer vers R2 et tout s’est parfaitement déroulé. Toutes les images utilisent désormais l’URL CDN S3. Cependant, j’ai remarqué un problème : les avatars mettent beaucoup de temps à se charger. En moyenne, cela prend environ 3 à 4 secondes, que je clique sur l’avatar d’un utilisateur ou que je consulte un message. Est-ce normal ?

hmmm, je soupçonne qu’il pourrait s’agir de l’un des 3 problèmes différents, mais le plus probable à mes yeux est le redimensionnement à la volée.

1. Redimensionnement à la volée des avatars

lorsque vous avez migré vos uploads vers R2, cela a déplacé les images originales ; cependant, discourse utilise de nombreuses tailles différentes d’avatars (par ex. 45px pour les messages, 120px pour la carte utilisateur).

si ces tailles spécifiques optimisées n’ont pas migré parfaitement, ou n’ont pas encore été générées, dscourse doit les générer de manière synchrone au moment où l’utilisateur clique dessus :

  1. discourse télécharge l’avatar original depuis R2 vers le serveur local
  2. le redimensionne en utilisant imagemagick
  3. télécharge la nouvelle taille vers R2
  4. redirige le navigateur vers la nouvelle URL, et ce processus prend 3 à 4 secondes

pour vérifier : actualisez fortement la page - si l’avatar met 3-4 secondes la première fois, mais se charge instantanément la deuxième fois, c’est exactement ce qui se passe.

pour corriger : cela se corrigera naturellement à mesure que les utilisateurs naviguent et que les tailles sont générées. mais vous pouvez le corriger instantanément, en forçant le serveur à pré-générer tous les avatars en arrière-plan en se connectant en ssh à votre serveur et en exécutant :

./launcher enter app
rake avatars:refresh

2. Le délai d’attente IPv6 de 3 secondes

si les avatars mettent 3-4 secondes à se charger à chaque fois, même après plusieurs actualisations, ils rencontrent probablement un délai d’attente réseau.

les points de terminaison de l’api cloudflare R2 sont double pile, c’est-à-dire qu’ils utilisent à la fois ipv4 et ipv6. si votre gouttelette de serveur a une adresse ipv6 qui lui est assignée, mais que la passerelle ipv6 de l’hôte n’est pas correctement routée, la connexion interne de ruby au compartiment R2 tentera ipv6 en premier, restera bloquée pendant 3 secondes (c’est le délai d’attente TCP par défaut de linux), échouera, puis réussira instantanément en utilisant ipv4.

pour vérifier : connectez-vous en ssh au serveur et exécutez :

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

s’il reste bloqué pendant quelques secondes et échoue, l’ipv6 du serveur est cassé, ce qui cause un délai de 3 secondes à chaque vérification de l’api S3 interne.

pour corriger : vous devrez soit corriger le routage ipv6 dans votre panneau de contrôle d’hôte, ou peut-être même désactiver ipv6 sur la gouttelette entièrement

3. Délais gravatar

si votre site est configuré pour vérifier les mises à jour gravatar, il peut pinguer les serveurs externes de gravatar avant de rendre l’avatar. si le serveur a une connexion sortante lente (également souvent liée à DNS ou ipv6), il est susceptible de bloquer le rendu de l’avatar.

pour vérifier : exécutez ceci sur votre serveur
curl -I -6 https://gravatar.com
s’il reste bloqué pendant 3 secondes, l’ipv6 est cassé (voir ci-dessus)

correction liée à gravatar : dans les paramètres de votre discourse, allez dans télécharger automatiquement les gravatars, désactivez-le temporairement, et voyez si cela corrige le problème - je ne pense pas que ce soit le problème, mais si c’est le cas, vous pouvez laisser le paramètre désactivé, ou corriger le routage ipv6 comme en 2 ci-dessus, ou peut-être changer le résolveur DNS.

Merci pour votre réponse rapide. Je pense avoir déjà essayé la commande rake avatars:refresh auparavant, mais je n’en suis pas absolument certain.

Ce qui fonctionnait autrefois pour moi afin d’ouvrir l’avatar immédiatement était de cliquer dessus une première fois ; la deuxième fois, il s’ouvrait instantanément. Mais cela est probablement dû à la mise en cache. De plus, je viens de tester votre deuxième astuce et elle renvoie un « HTTP/2 301 », avec plusieurs autres lignes. Même chose pour l’astuce 3. Je relancerai avatars:refresh dans quelques jours, car j’ai dû restaurer une capture d’état. Merci encore !

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

Oui, vu ta réponse, je suis presque certain qu’il s’agit du problème n°1, car les résultats de la commande curl pour Cloudflare et Gravatar semblent conformes aux attentes. Essaie rake avatars:refresh quand tu peux et tiens-moi au courant si ça marche.

Salut Lilly, j’ai toujours le même problème. Même après avoir exécuté rake avatars:refresh, le problème persiste, y compris avec /latest. J’ai essayé de vider le cache de mon navigateur et de Cloudflare, mais sans succès pour le moment. Faut-il attendre un peu ? Je teste sur un forum qui compte 4 500 utilisateurs.

ne videz plus le cache de votre navigateur ou celui de Cloudflare — lorsque vous exécutez rake avatars:refresh pour autant d’utilisateurs, cela ne se fait pas instantanément. Cela ajoute plutôt des milliers de tâches dans Sidekiq pour qu’elles soient traitées en arrière-plan, ce qui peut prendre plusieurs heures selon le CPU de votre serveur. Désolé pour cela, j’aurais dû mentionner Sidekiq et préciser que cela peut prendre un certain temps en fonction du nombre d’utilisateurs.

Rendez-vous sur your-forum.com/sidekiq/queues et surveillez la file d’attente. Attendez qu’elle soit complètement vidée. Une fois que Sidekiq a terminé, toutes les tailles devraient être stockées de manière permanente dans votre bucket R2, et je pense que le chargement de vos avatars devrait revenir à une vitesse normale.

D’accord, je pense qu’il se passe autre chose. Je n’ai rien dans mes files d’attente. Mais si je clique sur l’avatar de n’importe quel utilisateur, cela apparaît dans ‘tail -f log/production.log’ : Sent file /var/www/discourse/tmp/avatar_proxy/3689d91eb5e1013beef831c585b5e62edeeecbd6.jpeg (0.2ms)

Oh wow, d’accord. C’est probablement l’élément clé et cela pointe vers un problème différent.

avatar_proxy dans les journaux signifie généralement que Discourse refuse de servir l’avatar directement depuis le CDN Cloudflare R2. Au lieu de cela, Discourse intercepte activement la demande et télécharge l’image depuis R2 vers le dossier /tmp du serveur local, puis utilise Ruby pour servir l’image au navigateur. Je pense donc que cela contourne complètement le CDN et explique le délai de 3 secondes — je soupçonne que le serveur récupère et charge manuellement le fichier à chaque demande :grimacing:

Discourse utilise avatar_proxy dans quelques scénarios très spécifiques et c’est généralement un paramètre de confidentialité ou de sécurité qui force le serveur à masquer l’URL externe.

Vérifiez ces paramètres dans Admin > Paramètres du site :

Trouvez external system avatars url — s’il y a quelque chose dans cette case (comme /letter_avatar_proxy/v4/...), supprimez-le pour qu’il soit vide. Cela devrait empêcher Discourse de faire le proxy des avatars par défaut basés sur les lettres. Il vaut aussi la peine de vérifier uploaded avatars allowed groups et de vous assurer qu’il indique TL_0.

Vérifiez peut-être également DISCOURSE_S3_CDN_URL pour vous assurer qu’il est correct, sans barre oblique à la fin ni faute de frappe ?

Remappage des avatars personnalisés :
il semble probable que votre base de données contienne encore les URL brutes du bucket R2 au lieu de votre nouvelle URL CDN ; comme elles ne correspondent pas, votre forum les fait probablement passer par un proxy pour des raisons de sécurité.

Vérifiez dans la console Rails pour voir exactement avec quoi Discourse se bat :

./launcher enter app
rails c

Choisissez un nom d’utilisateur avec un avatar qui met du temps à charger.

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

Si la sortie renvoie une URL de bucket brute, vos remappages précédents n’ont pas tout capturé (peut-être qu’ils ont manqué un sous-domaine ou un schéma).

Pour corriger, connectez-vous en SSH à votre serveur, retournez dans votre conteneur à nouveau (pas dans Rails) (./launcher enter app), et exécutez l’outil de remappage (encore une fois, lol) pour remplacer l’URL brute par votre URL CDN :

discourse remap "https://<votre-url-cloudflare-brute>.r2.cloudflarestorage.com" "https://cdn.votre-domaine.com"

Ensuite, exécutez-le une deuxième fois en utilisant // au lieu de https:// au cas où.

Au fait, juste par curiosité, quel service d’hébergement utilisez-vous ? J’ai la même configuration générale que vous et je n’ai pas encore rencontré ce problème. Je suis donc aussi intéressé par votre configuration et je veux essayer de la reproduire d’une manière ou d’une autre.

L’URL que j’obtiens affiche l’URL du CDN S3, et je peux ouvrir l’image dans le navigateur.

Je vais laisser tomber S3 pour le moment, car je n’en ai pas vraiment besoin pour l’instant.

Et j’utilise Advinservers depuis longtemps.

Merci pour ton aide, c’est très apprécié.