J’essaie de configurer les téléchargements S3 et il semble que les téléchargements fonctionnent correctement, mais les requêtes GET échouent pour une raison étrange. Il semble que Discourse ajoute un “.cn” à l’URI de l’objet téléchargé.
Après avoir téléchargé l’image dans mon bucket S3, l’URL publique est :
Il semble que vous ayez peut-être collé accidentellement le même guide deux fois.
Lorsque vous mentionnez « les paramètres dans votre fichier yml », pourriez-vous préciser à quel fichier YAML vous faites référence ? Parlez-vous peut-être du fichier app.yml situé dans le dossier /var/discourse/containers ?
De plus, si je configure mon intégration S3/CloudFront directement via le fichier YAML, ces paramètres remplaceront-ils ceux configurés dans la section admin de Discourse ?
Voir les sujets liés qui décrivent comment configurer S3, mais oui, app.yml est ce que vous voulez changer (puisque vous n’avez pas mentionné web_only.yml)
Oui. Les saisir dans le fichier YML les masque de l’UX.
Après avoir reconstruit l’application avec ./launcher rebuild app, lorsque je visite le site web, il affiche simplement le chargeur sans rien charger. En inspectant l’onglet réseau, j’ai découvert qu’il ne parvenait pas à récupérer les actifs statiques précompilés (principalement des .js), ce que je suppose être parce qu’ils ne sont pas dans mon bucket S3. Vous pouvez vérifier ici : forum.hobiguru.com.
J’ai également essayé d’exécuter la tâche de migration rake, mais sans succès :
root@ubuntu-s-1vcpu-1gb-fra1-01-app:/var/www/discourse# rake uploads:migrate_to_s3 --trace
** Invoke uploads:migrate_to_s3 (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute uploads:migrate_to_s3
Veuillez noter que la migration vers S3 n'est actuellement pas réversible !
[CTRL+c] pour annuler, [ENTER] pour continuer
Migration des téléversements vers S3 pour 'default'...
Certains téléversements n'ont pas été migrés vers le nouveau schéma. L'exécution de la migration peut prendre un certain temps...
rake aborted!
FileStore::ToS3MigrationError: Certains téléversements n'ont pas pu être migrés vers le nouveau schéma. Vous devez corriger cela manuellement. (FileStore::ToS3MigrationError)
/var/www/discourse/lib/file_store/to_s3_migration.rb:156:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:59:in `migrate'
/var/www/discourse/lib/tasks/uploads.rake:126:in `migrate_to_s3'
/var/www/discourse/lib/tasks/uploads.rake:106:in `block in migrate_to_s3_all_sites'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:36:in `each_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:104:in `migrate_to_s3_all_sites'
/var/www/discourse/lib/tasks/uploads.rake:100:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:281:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:281:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:281:in `execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:199:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/task.rb:188:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:188:in `invoke_task'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:138:in `block (2 levels) in top_level'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:138:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:138:in `block in top_level'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:147:in `run_with_threads'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:132:in `top_level'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:83:in `block in run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:214:in `standard_exception_handling'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/lib/rake/application.rb:80:in `run'
bin/rake:13:in `<top (required)>'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli.rb:455:in `exec'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli.rb:35:in `dispatch'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/cli.rb:29:in `start'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/exe/bundle:28:in `block in <top (required)>'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/exe/bundle:20:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
Mon intention initiale était d’utiliser S3 uniquement pour stocker les téléversements des utilisateurs, et j’ai ajouté le CDN juste pour gérer cela. Cependant, je rencontre maintenant un nouveau problème : les actifs statiques de mon application sont également servis via le CDN, ce que je n’avais pas prévu.
Y a-t-il un moyen de téléverser tous les actifs statiques au lancement de l’application dans le bucket S3, puis de les faire servir via le CDN, ou un moyen de ne servir que les téléversements des utilisateurs via le CDN, ou existe-t-il une meilleure solution pour cela ?
Peut-être que je rate encore quelque chose d’évident ? Je ne sais pas.
Merci pour votre aide !
Je soupçonne que c’est parce que vous n’avez pas suivi les instructions.
Oui. Je comprends. C’est possible, mais vous n’avez pas réussi à le faire fonctionner. C’est la méthode recommandée ; elle est bien documentée et des centaines de personnes l’utilisent ainsi.
Néanmoins, les téléchargements d’utilisateurs ne fonctionnent toujours pas correctement. Après le téléchargement dans le bucket S3 (correctement), l’image est servie comme suit :
//my-bucket-eu.my-bucket-eu/original/1X/7f242572bdb45b65ded727c13366fe490541358f.jpeg
ce qui n’est bien sûr pas un chemin S3 ou CDN valide.
Dans le guide auquel vous faites référence, il y a cette section qui semble pertinente :
DISCOURSE_CDN_URL est un CDN qui pointe vers votre nom d'hôte Discourse et met en cache les requêtes. Il sera principalement utilisé pour les actifs téléchargeables : CSS et autres actifs de thème.
DISCOURSE_S3_CDN_URL est un CDN qui pointe vers votre bucket de stockage d'objets et met en cache les requêtes. Il sera principalement utilisé pour les actifs téléchargeables : JS, images et téléchargements d'utilisateurs.
Nous recommandons que ces deux soient différents et que les administrateurs les configurent tous les deux.
Cependant, je ne suis pas sûr de ce qu’il faut définir comme DISCOURSE_CDN_URL ? Dois-je le définir à la même valeur que DISCOURSE_S3_CDN_URL: https://dsxxxxx2qn.cloudfront.net ou créer une instance CDN distincte ?
Encore une fois, peut-être que c’est quelque chose de totalement différent
Salut Jake, je ne suis pas sûr de bien comprendre ce que tu veux dire. Pourrais-tu développer un peu plus ?
Voulais-tu dire qu’au lieu de définir le bucket S3 comme origine du CDN, je devrais définir mon domaine forum.hobiguru.com comme origine ? Si c’est le cas, je ne pense pas que cela changerait quoi que ce soit car c’est le forum discourse qui génère ces URL qui ne mènent nulle part, par exemple //my-bucket-eu.my-bucket-eu/original/1X/7f242572bdb45b65ded727c13366fe490541358f.jpeg
J’ai ajouté DISCOURSE_CDN_URL: https://dsuxxxhrz2qn.cloudfront.net et j’attends maintenant que l’application se reconstruise
MISE À JOUR : non, cela n’a pas fonctionné non plus
Vous ne pouvez pas nommer un sous-domaine uniquement dans app.yml. Personne ne peut l’utiliser sans informations DNS appropriées. Et comme la diffusion de vos fichiers se fait depuis AWS, vous devez également configurer ce côté-là si vous souhaitez utiliser un CDN.
Mais encore une fois. Les utilisateurs voient l’URL de Discourse, s’ils veulent la voir. Il est assez rare que quelqu’un d’autre qu’un administrateur fasse quelque chose qui le souhaite. Et les utilisateurs ne voient pratiquement jamais l’URL des médias ou d’autres fichiers statiques.
Donc, de mon point de vue, vous perdez votre temps pour rien si vous ne voulez pas utiliser de CDN. Et cela peut être judicieux si vous avez une audience mondiale, et que certains d’entre eux sont derrière des connexions de mauvaise qualité au niveau de l’État.
Je vis en Finlande. Je ne retire aucun avantage réel si un site de l’autre côté du monde, en Australie, utilise un CDN (depuis un serveur situé à 1000 km de chez moi). Le véritable goulot d’étranglement vient de la façon dont ce site est construit, par exemple s’il utilise beaucoup d’appels PHP inutiles sans ressources suffisantes.
Mais fondamentalement, vous ne pouvez pas utiliser une URL cdn.example.tld sans mettre cdn au moins dans le DNS.
En fait, je ne veux pas du tout utiliser de CDN — je veux juste que toutes les téléversements des utilisateurs soient stockés dans S3 et servis directement à partir de là, bien que CloudFront soit vraiment une meilleure solution que S3 directement.
« Vous ne pouvez pas nommer un sous-domaine uniquement dans app.yml. Personne ne peut l’utiliser sans informations DNS appropriées. Et comme la diffusion de vos fichiers se fait depuis AWS, vous devez également configurer ce côté-là, si vous voulez utiliser un CDN. »
Je suis désolé, mais je n’ai pas tout à fait compris ce que vous vouliez dire par ce paragraphe. Pourriez-vous élaborer un peu plus ou clarifier ? Dites-vous que je dois configurer des enregistrements DNS pour mon bucket S3 ou qu’il y a quelque chose de spécifique que je dois ajuster du côté d’AWS ?
Je voulais faire suite à mon précédent message et partager que j’ai fait quelques progrès.
Ce qui fonctionne maintenant
Les téléchargements d’utilisateurs sont correctement servis depuis mon bucket S3 via le CDN (CloudFront), c’est donc une bonne nouvelle !
Cependant, j’ai toujours un problème avec les assets précompilés
Les assets précompilés ne sont toujours pas servis correctement depuis le CDN.
Lorsque je définis DISCOURSE_CDN_URL sur l’URL CloudFront (c’est-à-dire https://dsuqioxhrz2qn.cloudfront.net), les URL des assets précompilés deviennent :
Le problème est que ces chemins n’existent pas dans mon bucket S3. Les assets précompilés sont téléchargés sous le dossier /assets/* dans S3 (par exemple, /assets/locales, /assets/plugins, /assets/scripts), mais il n’y a pas de dossier /stylesheets/ et bien sûr, le chargement de ces URL entraîne une erreur 403 Forbidden.
Si, cependant, je change DISCOURSE_CDN_URL: https://forum.hobiguru.com, alors mon forum fonctionne correctement, mais les assets sont maintenant servis depuis le serveur (par exemple, https://forum.hobiguru.com/) et non depuis le CDN (par exemple, https://forum.hobiguru.com/stylesheets/admin_308d905aa5c03567866fec50e9a28d8721ab0463.css?__ws=forum.hobiguru.com)
Ma configuration actuelle (pour le contexte) est :
app.yaml
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: eu-central-1
DISCOURSE_S3_ACCESS_KEY_ID: AKIA......LQMB
DISCOURSE_S3_SECRET_ACCESS_KEY: PaXQu7pKN.....fJNY
DISCOURSE_S3_CDN_URL: https://dsuqioxhrz2qn.cloudfront.net # Assurez-vous que l'URL du CDN pointe vers CloudFront
DISCOURSE_CDN_URL: https://forum.hobigur.com # REMARQUEZ CECI !
DISCOURSE_S3_BUCKET: hobiguru-s3-bucket-eu
Il semble qu’après la précompilation, les assets soient téléchargés dans S3 selon une certaine structure, mais lorsqu’ils sont chargés via le CDN, le chemin vers les objets est un peu décalé.