Kann Bucket in S3 nicht einrichten

Hallo,

Ich versuche, S3-Uploads einzurichten, und es scheint, dass die Uploads korrekt funktionieren, aber die GET-Anfragen aus einem seltsamen Grund fehlschlagen. Es scheint, dass Discourse der URI des hochgeladenen Objekts ein “.cn” hinzufügt.

Nach dem Hochladen des Bildes in meinen S3-Bucket ist die öffentliche URL:

https://hobig...bucket-eu.s3.eu-central-1.amazonaws.com/original/1X/5e894113...48918.jpeg

aber wenn ich im Browser nachsehe, versucht mein Discourse-Forum zu laden (beachten Sie das .cn):

https://hobig...bucket-eu.s3.eu-central-1.amazonaws.com.cn/original/1X/5e894113...48918.jpeg

Weiß jemand, warum das passiert?

Hier sind meine Admin-Einstellungen:

Sie sollten die Anweisungen in Konfigurieren eines S3-kompatiblen Objektspeichers für Uploads und/oder Set up file and image uploads to S3 befolgen und diese Einstellungen in Ihre yml-Datei anstatt in die Datenbank/UX eintragen.
Sie müssen keinen Endpunkt für AWS konfigurieren. Sie möchten jedoch ein CDN konfigurieren.

1 „Gefällt mir“

Hallo @pfaffman,

Es scheint, als hätten Sie versehentlich dieselbe Anleitung zweimal eingefügt.

Wenn Sie „Einstellungen in Ihrer YML-Datei“ erwähnen, könnten Sie bitte klären, auf welche YAML-Datei Sie sich beziehen? Sprechen Sie vielleicht über die Datei app.yml im Ordner /var/discourse/containers?

Außerdem, wenn ich meine S3/CloudFront-Integration direkt über die YAML-Datei konfiguriere, würden diese Einstellungen das überschreiben, was im Admin-Bereich von Discourse konfiguriert ist?

Vielen Dank!

Entschuldigung. Einer davon hätte Set up file and image uploads to S3 sein sollen.

Siehe die verlinkten Themen, die beschreiben, wie S3 konfiguriert wird, aber ja, die app.yml ist diejenige, die Sie ändern möchten (da Sie web_only.yml nicht erwähnt haben).

Ja. Die Eingabe in der YML-Datei blendet sie aus der Benutzeroberfläche aus.

Hallo @pfaffman,

Ich habe meinen S3-Bucket, mein CloudFront-Setup und die CloudFront-Origin, die auf meinen S3-Bucket eingestellt ist. Hier ist meine aktuelle app.yml-Konfiguration:

ENV:
  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: eu-central-1
  DISCOURSE_S3_ACCESS_KEY_ID: AKIAWPLPUxxxxxx
  DISCOURSE_S3_SECRET_ACCESS_KEY: PaXQu7pKxxxx
  DISCOURSE_S3_CDN_URL: https://dsuxxxhrz2qn.cloudfront.net
  DISCOURSE_S3_BUCKET: hobigxxxxbucket-eu

Nachdem ich die App mit ./launcher rebuild app neu erstellt habe, zeigt die Website beim Besuch nur den Lader an, ohne etwas zu laden. Bei der Inspektion des Netzwerk-Tabs habe ich festgestellt, dass die vorcompilierten statischen Assets (hauptsächlich .js) nicht abgerufen werden können, was ich vermute, weil sie sich nicht in meinem S3-Bucket befinden. Sie können es hier überprüfen: forum.hobiguru.com.

Ich habe auch versucht, die Migration-Rake-Aufgabe auszuführen, aber ohne Erfolg:

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
Bitte beachten Sie, dass die Migration zu S3 derzeit nicht rückgängig gemacht werden kann!
[CTRL+c] zum Abbrechen, [ENTER] zum Fortfahren
Migrating uploads to S3 for 'default'...
Einige Uploads wurden nicht in das neue Schema migriert. Die Ausführung der Migration kann eine Weile dauern...
rake aborted!
FileStore::ToS3MigrationError: Some uploads could not be migrated to the new scheme. You need to fix this manually. (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'

Meine ursprüngliche Absicht war es, S3 nur zum Speichern von Benutzer-Uploads zu verwenden, und ich habe den CDN nur hinzugefügt, um dies zu handhaben. Jetzt stehe ich jedoch vor einem neuen Problem – die statischen Assets meiner App werden ebenfalls über den CDN ausgeliefert, was ich nicht beabsichtigt hatte. :confused:

Gibt es eine Möglichkeit, alle statischen Assets beim Start der App in den S3-Bucket hochzuladen und sie dann über den CDN ausliefern zu lassen, oder eine Möglichkeit, nur die Uploads von Benutzern über den CDN ausliefern zu lassen, oder gibt es eine bessere Lösung dafür?

Vielleicht übersehe ich ja etwas Offensichtliches? Keine Ahnung.
Vielen Dank für Ihre Hilfe!

Ich vermute, das liegt daran, dass du die Anweisungen nicht befolgt hast.

Ja. Ich verstehe. Das ist möglich, aber du konntest das nicht zum Laufen bringen. Dies ist der empfohlene Weg; er ist gut dokumentiert und Hunderte von Leuten machen es auf diese Weise.

1 „Gefällt mir“

Entschuldigung, Sie haben Recht, ich habe diesen Teil ausgelassen. Ich habe Folgendes in meine app.yml eingefügt und jetzt lädt das Forum korrekt:

after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets
          - sudo -E -u discourse bundle exec rake s3:expire_missing_assets

Dennoch funktionieren die Benutzer-Uploads immer noch nicht richtig. Nach dem (korrekten) Upload in den S3-Bucket wird das Bild wie folgt ausgeliefert:

//my-bucket-eu.my-bucket-eu/original/1X/7f242572bdb45b65ded727c13366fe490541358f.jpeg
was natürlich kein gültiger S3- oder CDN-Pfad ist.

In der Anleitung, auf die Sie sich beziehen, gibt es diesen Abschnitt, der relevant zu sein scheint:

DISCOURSE_CDN_URL ist ein CDN, das auf Ihren Discourse-Hostnamen verweist und Anfragen zwischenspeichert. Es wird hauptsächlich für abrufbare Assets verwendet: CSS und andere Theme-Assets.

DISCOURSE_S3_CDN_URL ist ein CDN, das auf Ihren Object Storage Bucket verweist und Anfragen zwischenspeichert. Es wird hauptsächlich für pushbare Assets verwendet: JS, Bilder und Benutzer-Uploads.

Wir empfehlen, diese unterschiedlich zu konfigurieren und dass Administratoren beide einstellen.

Ich bin mir jedoch nicht sicher, was ich als DISCOURSE_CDN_URL festlegen soll? Soll ich es auf denselben Wert wie DISCOURSE_S3_CDN_URL: https://dsxxxxx2qn.cloudfront.net setzen oder eine separate CDN-Instanz erstellen?

Oder vielleicht ist es etwas ganz anderes :confused:

Vielen Dank für all die Hilfe!

Sie müssen CDN konfigurieren und es mit Ihrer gewünschten Domain auf der AWS-Seite verwenden. Plus in DNS.

Aber warum? Praktisch niemand sieht diese URL.

1 „Gefällt mir“

Hallo Jake, ich bin mir nicht sicher, ob ich richtig verstehe, was du meinst. Könntest du das bitte etwas genauer erläutern?

Meintest du vielleicht, dass ich anstatt des S3-Buckets als Ursprung des CDN meine Domain forum.hobiguru.com als Ursprung einrichten sollte? Wenn ja, glaube ich nicht, dass das etwas ändern würde, da das Discourse-Forum diese URLs generiert, die ins Leere führen, z. B. //my-bucket-eu.my-bucket-eu/original/1X/7f242572bdb45b65ded727c13366fe490541358f.jpeg

Ich habe DISCOURSE_CDN_URL: https://dsuxxxhrz2qn.cloudfront.net hinzugefügt und warte nun auf den Neuaufbau der App :crossed_fingers:

UPDATE: Nein, das hat auch nicht funktioniert :/\n\nIch weiß deine Hilfe wirklich zu schätzen.\nDanke

Sie können eine Subdomain nicht nur in app.yml benennen. Niemand kann sie ohne entsprechende DNS-Informationen verwenden. Und da Ihre Dateien von AWS bereitgestellt werden, müssen Sie auch diese Seite konfigurieren, wenn Sie CDN verwenden möchten.

Aber wieder. Benutzer sehen die URL von Disourse, wenn sie sie sehen wollen. Selten will jemand anderes als ein Administrator etwas tun. Und Benutzer sehen praktisch nie die URL von Medien oder anderen statischen Dateien.

Mein Standpunkt ist also, dass Sie Ihre Zeit für nichts verschwenden, wenn Sie kein CDN nutzen wollen. Und das kann klug sein, wenn Sie ein globales Publikum haben und einige von ihnen über schlechte staatliche Verbindungen verfügen.

Ich lebe in Finnland. Ich habe keine wirklichen Vorteile, wenn eine Website auf der anderen Seite der Welt, in Australien, CDN nutzt (von einem Server, der 1000 km von mir entfernt ist). Der eigentliche Flaschenhals ergibt sich daraus, wie diese Website aufgebaut ist, z. B. wenn viele unnötige PHP-Aufrufe ohne ausreichende Ressourcen verwendet werden.

Aber im Grunde können Sie keine URL cdn.example.tld verwenden, ohne cdn zumindest in DNS einzutragen.

Hallo @Jagster

Eigentlich möchte ich überhaupt kein CDN verwenden – ich möchte nur, dass alle Benutzer-Uploads in S3 gespeichert und direkt von dort ausgeliefert werden, obwohl CloudFront wirklich eine bessere Lösung ist als S3 direkt.

Mein Problem trat auf, als ich versuchte, S3 einzurichten (speziell für die Auslieferung von Assets, nicht für Uploads), und @pfaffman schlug vor, dass ich dem Leitfaden Konfigurieren eines S3-kompatiblen Objektspeicheranbieters für Uploads folgen und ein CDN konfigurieren sollte.

Bezüglich deines Kommentars:

„Du kannst eine Subdomain nicht nur in app.yml benennen. Niemand kann sie ohne richtige DNS-Informationen verwenden. Und da deine Dateien von AWS ausgeliefert werden, musst du auch diese Seite konfigurieren, wenn du ein CDN verwenden möchtest.“

Es tut mir leid, aber ich habe nicht ganz verstanden, was du mit diesem Absatz meintest. Könntest du das etwas ausführlicher erläutern oder klären? Meinst du, ich muss DNS-Einträge für meinen S3-Bucket konfigurieren oder gibt es etwas Bestimmtes, das ich auf der AWS-Seite anpassen muss?

Vielen Dank im Voraus für deine Hilfe!

Hallo zusammen,

ich wollte auf meinen vorherigen Beitrag zurückkommen und mitteilen, dass ich einige Fortschritte gemacht habe.

Was jetzt funktioniert

  • Benutzer-Uploads werden korrekt von meinem S3-Bucket über das CDN (CloudFront) bereitgestellt, das ist großartig!

Ich habe jedoch immer noch ein Problem mit den vorkompilierten Assets

Die vorkompilierten Assets werden immer noch nicht korrekt vom CDN bereitgestellt.

Wenn ich DISCOURSE_CDN_URL auf die CloudFront-URL (d. h. https://dsuqioxhrz2qn.cloudfront.net) setze, werden die URLs der vorkompilierten Assets zu:

•	https://dsuqioxhrz2qn.cloudfront.net/stylesheets/color_definitions_shades-of-blue_7_1_e6f11758f9c015d1e5ed9b08c437e9c5c267c932.css?__ws=forum.hobiguru.com
•	https://dsuqioxhrz2qn.cloudfront.net/stylesheets/discourse-presence_308d905aa5c03567866fec50e9a28d8721ab0463.css

Das Problem ist, dass diese Pfade nicht in meinem S3-Bucket existieren. Die vorkompilierten Assets werden unter dem Ordner /assets/* in S3 hochgeladen (z. B. /assets/locales, /assets/plugins, /assets/scripts), aber es gibt keinen /stylesheets/-Ordner, und das Laden dieser URLs führt natürlich zu einem 403 Forbidden-Fehler.

Wenn ich jedoch DISCOURSE_CDN_URL: https://forum.hobiguru.com ändere, funktioniert mein Forum korrekt, aber die Assets werden jetzt vom Server (z. B. https://forum.hobiguru.com/) und nicht vom CDN bereitgestellt (z. B. https://forum.hobiguru.com/stylesheets/admin_308d905aa5c03567866fec50e9a28d8721ab0463.css?__ws=forum.hobiguru.com)

Mein aktuelles Setup (zum Kontext) ist:

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_BUCKET: hobiguru-s3-bucket-eu
DISCOURSE_CDN_URL: https://dsuqioxhrz2qn.cloudfront.net  # Stelle sicher, dass die CDN-URL auf CloudFront zeigt
DISCOURSE_CDN_URL: https://forum.hobigur.com # BEACHTE DAS!

und die Precompile-Hooks:

hooks:
  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets
          - sudo -E -u discourse bundle exec rake s3:expire_missing_assets

Es scheint, dass nach dem Vorkompilieren die Assets in S3 in einer bestimmten Struktur hochgeladen werden, aber wenn sie dann über das CDN geladen werden, ist der Pfad zu den Objekten etwas falsch.