Rake uploads:migrate_from_s3 schlägt fehl

Ich habe die Schritte hier befolgt, meine gesamte Seite gesichert, meinen AWS S3-Bucket geklont, den Bucket-Namen in den Discourse-Einstellungen vom Original-Bucket in den Backup-Bucket geändert und das Kontrollkästchen „Uploads zu S3" in den Einstellungen deaktiviert.

Jetzt bin ich endlich bereit, mit der Migration von S3 zu beginnen … und sie schlägt fehl. :frowning:

Die Fehlermeldung

root@ubuntu:/var/www/discourse# rake uploads:migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `downcase' for nil:NilClass
/var/www/discourse/app/models/global_setting.rb:107:in `s3_bucket_name'
/var/www/discourse/app/models/site_setting.rb:157:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.2.2/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.2.2/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3
(See full trace by running task with --trace)

(Hier ist die Zeile auf GitHub, an der der Fehler auftritt – ich vermute, es kann den Wert von s3_bucket nicht abrufen?)

Weitere Versuche

  • Ich habe versucht, die Zugangsdaten über die Befehlszeile hinzuzufügen, aber das hat nichts geändert. Also:
    DISCOURSE_S3_BUCKET="dn-forum-storage-backup" DISCOURSE_S3_REGION="us-east-1" DISCOURSE_S3_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxx" DISCOURSE_S3_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxx" DISCOURSE_S3_CDN_URL="https://dn-forum-storage-backup.s3.us-east-1.amazonaws.com" rake uploads:migrate_from_s3

  • Ich habe auch versucht, den S3-Bucket-Namen in meinen Einstellungen wieder auf den ursprünglichen Bucket-Namen zurückzusetzen, aber leider ohne Erfolg, das Ergebnis ist dasselbe.

  • Ich habe zudem versucht, die Anwendung neu zu erstellen. Gleiches Ergebnis.

@vinothkannans, weißt du, was hier los ist?

Bitte helft mir, Discourse-Freunde!

P.S. Kleine Randnotiz: rake --tasks listet diesen Task oder irgendeinen Task, der mit uploads beginnt, nicht auf. Ich bin mir nicht sicher, ob das etwas bedeutet.

Möglicherweise verwandtes Problem? cc @mcdanlj

@pnoeric ja, das sieht genau nach demselben aus. Ich habe zu dieser Issue keine Rückmeldung erhalten, was genau die Absicht hinter SiteSettings im Vergleich zu GlobalSettings für S3 ist. Daher kann ich im Moment nichts weiter empfehlen, als es über die Konfiguration zu SiteSettings hinzuzufügen (Punkt 1 in meinem Beitrag).

Hey, danke für diese Antwort… Ich bin mir nicht einmal sicher, was SiteSettings im Vergleich zu GlobalSettings bedeutet – ich bin nicht so gut im RoR-Coding und verstehe das gesamte Setup nicht ausreichend. Ich folge einfach den grundlegenden Anweisungen. :wink:

Aber hoffentlich meldet sich @vinothkannans auch zu Wort; ich glaube, er hat den Code für die Migrate-Aufgaben geschrieben. Oder jemand anderes vom @team, der es vielleicht weiß…

Lasst uns dieses Thema im Auge behalten…

s3_bucket befindet sich in GlobalSettings, das normalerweise aus der Datei config/discourse.conf festgelegt wird, welche aus Umgebungsvariablen in der Datei app.yml erstellt wird. SiteSettings sind Einstellungen, die Sie in den Admin-Einstellungen der App ändern können.

Es scheint, als könnte man bei der ursprünglichen Erstellung die S3-Konfiguration nur durch einen Neuaufbau der App ändern, während es in jüngerer Zeit möglich geworden ist, die Daten in den Admin-Einstellungen einzugeben. Ich kann nicht sagen, was die Absicht dahinter war, beim Hinzufügen der Möglichkeit, S3 in SiteSettings zu konfigurieren, keine vollständige Migration durchzuführen.

[Edit: Ich habe die beiden Begriffe beim ersten Posten dieser Antwort versehentlich vertauscht.]

Hmmm @mcdanlj, nur zur Sicherheit: Du hast es also immer noch nicht geschafft, migrate_from_s3 tatsächlich zum Laufen zu bringen, oder?

Ich habe nichts dagegen, alle erforderlichen Einstellungen, Low-Level-Dateien oder was auch immer zu bearbeiten. Ich muss einfach so schnell wie möglich von S3 weg, da es mir ein Vermögen kostet.

Hallo @pnoeric und @mcdanlj,

Ein Ansatz zur Fehleranalyse könnte darin bestehen, in die Rails-Konsole zu gehen und einen Blick auf die S3-Site-Einstellungen zu werfen?

Zum Beispiel in einer einfachen, standardmäßigen OOTB-Discourse-Docker-Single-Container-Standalone-App:

root@localhost:~# docker exec -it app rails c
[1] pry(main)> SiteSetting.s3_upload_bucket
=> ""
[2] pry(main)> SiteSetting.enable_s3_uploads
=> false
[3] pry(main)> 

Vergleich der SiteSettings (über die Rails-Konsole) mit den Standardwerten, die hier aufgeführt sind:

Vielleicht könnte eine Fehlersuche auf diese Weise hilfreich sein (ich habe keine Ahnung, da wir AWS oder S3 nicht nutzen)? Vielleicht hilft die Rails-Konsole ein wenig?

rake --tasks zeigt nur Aufgaben an, die eine Beschreibung haben. Alle verfügbaren Aufgaben kannst du über rake -AT einsehen.

Ich glaube nicht, dass es helfen wird, da ich diese Aufgaben vor kurzem auf einer Testseite ausgeführt habe. Beide scheinen davon abzuhängen, dass S3-Variablen in der env definiert sind. Allerdings war das vor ein paar Monaten, und migrate_from_s3 hat bei mir nicht wirklich funktioniert.

Eine knifflige Frage. Ich habe s3_bucket in config/discourse.conf wie im von dir verlinkten Beitrag erwähnt gesetzt, was diesen spezifischen Fehler behoben hat, wie ich dort auch festgehalten habe.

Diese Datei befindet sich innerhalb des Containers (./launcher enter app). Beachte, dass du für die Beständigkeit nach einem ./launcher rebuild app auch DISCOURSE_S3_BUCKET im env-Abschnitt deiner containers/app.yml-Datei hinzufügen musst.

Der Grund, warum ich das als Entwickler-Beitrag und nicht als Support-Anfrage gepostet habe, war, dass ich es bereits behoben hatte; ich wollte wissen, was Entwickler als die richtige Lösung betrachten, während ich weiterhin daran feile.

Da ich etwa 100 GB Dateien in S3 habe, gehe ich sehr vorsichtig vor. Ich habe ein Limit für die zu prüfenden Beiträge implementiert, und als Nächstes muss ich ein Limit für die zu ändernden Beiträge umsetzen. Ich versuche es Schritt für Schritt. Dass es sich dabei offenbar um selten genutzten Code handelt und ich diesen Fehler wiederholt gesehen habe, macht mir Sorgen wegen Code-Rot. Ich möchte nicht plötzlich meine gesamte Website aufgrund eines Fehlers verunstalten, und hier liegt die Gefahr, genau diesen Fehler zu machen.

  • Für upload://-Uploads (bei mir bedeutet das nicht-Video-Uploads) scheint es bisher zu funktionieren. Ich arbeite einen nach dem anderen ab und überprüfe den betroffenen Beitrag, um sicherzustellen, dass alles korrekt funktioniert.

  • Für Uploads, die nicht die upload://-Syntax verwenden (bei mir bedeutet das meines Wissens nach Video-Uploads), bei denen ein direkter Verweis auf die URL in S3 steht, werden die URLs verfälscht. Das ist kein hartnäckiger Fehler, sobald ich herausgefunden habe, was ich genau ändern muss, aber das habe ich noch nicht getan. Das wird also wahrscheinlich einer der PRs sein, die ich bald einreichen werde.

Das ist für mich ein Projekt in meiner Freizeit, daher kann ich keine Zeitversprechen geben.

Aha, vielen Dank! Ich werde es versuchen.

Ugh, immer noch kein Erfolg, @neounix @mcdanlj @vinothkannans. Immer noch ein Fehler. Aber wenigstens gibt es jetzt eine neue/andere Fehlermeldung…

Hier ist, was ich heute versucht habe:

  1. Auf die neueste Discourse-Version aktualisiert, nur um sicherzugehen.

  2. Meinen s3_bucket in config/discourse.conf hinzugefügt.

  3. ./launcher enter app ausgeführt.

  4. containers/app.yml bearbeitet und die Variable DISCOURSE_S3_BUCKET hinzugefügt.

  5. rake uploads:migrate_from_s3 versucht, und jetzt scheitert es mit einer neuen Fehlermeldung (zuvor war downcase das Problem, jetzt scheint es start_with? zu sein):

/var/www/discourse# rake uploads:migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `start_with?' for nil:NilClass
/var/www/discourse/app/models/site_setting.rb:161:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3
(See full trace by running task with --trace)
  1. Also habe ich ./launcher rebuild app versucht.

  2. Und erneut ./launcher enter app, rake uploads:migrate_from_s3.

Genau dasselbe Problem:

/var/www/discourse# rake uploads:migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `start_with?' for nil:NilClass
/var/www/discourse/app/models/site_setting.rb:161:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3
(See full trace by running task with --trace)

Hast du noch andere Ideen?

Dieser Prozess ist übrigens eine echte Qual – ich muss den Ausfall des Forums Tage im Voraus planen und ankündigen, dann am Tag selbst die Hauptseite so ändern, dass niemand mehr ins Forum kommt, und dann den Forum-Server bei DigitalOcean herunterfahren und ein Snapshot erstellen, bevor ich fortfahre. Das allein dauert schon etwa 30 Minuten. Dann starte ich ihn wieder und kann die oben genannten Schritte versuchen. Ich bereue es zutiefst, Amazon S3 für die Medienspeicherung eingerichtet zu haben! Ich habe Stunden damit verbracht, diese Entscheidung rückgängig zu machen, und immer noch kein Erfolg (und trotzdem eine riesige Rechnung von Amazon jeden Monat). Ich würde gerne herausfinden, woran es liegt. Wie kann ich helfen?

Diese Zeile lautet:

        if SiteSetting.Upload.s3_region.start_with?("cn-")

Anscheinend wird auch s3_region erwartet; mir ist nicht klar, warum ich darauf nicht gestoßen bin.

Ich verstehe Ihre Logik nicht ganz; meine eigene Migration von etwa 100 GB Inhalt plane ich live durchzuführen, nach einem normalen Site-Backup. Ich beginne jedoch klein, weshalb ich daran arbeite, die Menge der gleichzeitig migrierten Daten zu begrenzen. Eine Warnung: Der Code scheint für die Übersetzung von URLs im wörtlichen Sinne falsch zu sein, wie ich bei Video-Uploads sehe. Wenn Sie also Video-Uploads erlaubt haben, könnten Sie mit dem Code im aktuellen Zustand dort auf Probleme stoßen.

Vielleicht sollte ich also alle oben genannten Schritte wiederholen, aber ich werde s3_bucket, s3_region, s3_cnd_url, s3_secret_access_key usw. (im Grunde jede Variable, die ich habe) in die conf- und yml-Dateien einfügen? Ich gebe lieber mehr als vielleicht nötig, damit das Ding einfach funktioniert.

Ich habe gesehen, dass jemand vom Discourse-Team empfohlen hat, vor Beginn dieses Übergangs eine vollständige Sicherung der lokalen Website zu erstellen. Das erfordert, dass ich meinen Digital Ocean-Server offline nehme. :frowning:

Richtig. Ich fange auch klein an … jedes Mal, wenn ich es versuche, migriere ich 0 Dateien. :grin:

Zum Glück dürfen Mitglieder in meinem Forum nur JPG, GIF und PNG hochladen, also sollte das in Ordnung sein.

Kreuzen wir die Finger.

Sicherung und Snapshot sind nicht dasselbe. Ein Snapshot ist die grobste Form der Sicherung. Die Admin-Konsole verfügt über eine Sicherungsfunktion. Stellen Sie sicher, dass Sie diese zunächst in den Einstellungen so konfigurieren, dass auch Miniaturansichten gesichert werden.

Da Sie nun wissen, dass Sie Ihre Site nicht herunterfahren müssen, können Sie entspannter vorgehen. Sie können batch_migrate_from_s3 verwenden, um höchstens eine bestimmte Anzahl von Uploads zu migrieren. Derzeit begrenzt dies eher die berücksichtigten Beiträge als die durchgeführten Migrationen – ein Fehler, den ich in einem zukünftigen PR beheben werde. Ich muss jedoch auch den Fehler beim Hochladen von Videos beheben, und ich würde gerne eine Rückmeldung ausgeben, da einer der Gründe für das Limit darin besteht, in betroffenen Beiträgen bestätigen zu können, dass die Migration erfolgreich war.

Ich werde dies wahrscheinlich in den nächsten 1–2 Monaten durchführen. Wenn Sie also warten möchten, könnte es sich lohnen, noch einige weitere Monate S3 zu bezahlen. Das liegt bei Ihnen, und ich gebe keine Versprechen, sondern stelle nur meine Absicht dar.

@pnoeric Da dir die Verfügbarkeit der Seite wichtig ist, wollte ich dir mitteilen, was ich bisher gelernt habe.

Wie bereits erwähnt, habe ich die Migration live durchgeführt. Wenn ich die Migration nicht drossle, werden die Warteschlangen, die Aufgaben wie das Benachrichtigen von Nutzern über Aktivitäten anderer erledigen, verstopft, und die Benutzererfahrung auf der Seite leidet.

Ich habe etwa 500 Beiträge mit Videos und rund 30.000 Beiträge mit Bildern migriert, was insgesamt etwa zwei Wochen in Anspruch nahm.

Falls du den von mir verwendeten Code ausprobieren möchtest, findest du ihn aktuell hier:

Du kannst ihn herunterladen und in deine App kopieren, um den aktuellen Inhalt von lib/tasks/uploads.rake zu ersetzen.

Mit diesem Code kannst du beispielsweise Folgendes tun:

bin/rake uploads:batch_migrate_from_s3[100,1000]

Dadurch werden nur insgesamt 1000 Beiträge mit Uploads berücksichtigt, und Dateien werden von maximal 100 Beiträgen migriert, bevor der Vorgang gestoppt wird. Jedes Mal, wenn ein Beitrag nach der Migration seiner Uploads tatsächlich geändert wird, wartet das Skript, bis die Warteschlange leer ist, bevor es mit dem nächsten fortfährt.

Wenn du die Datei einfügst, wird dies zukünftige Site-Updates unterbrechen, bis du die Änderung rückgängig machst. Der einfachste Weg, dies nach Abschluss deiner Arbeit rückgängig zu machen, ist ./launcher rebuild app (obwohl ich als Entwickler git checkout HEAD lib/tasks/uploads.rake verwende, um meine Änderungen rückgängig zu machen…)

Ich habe festgestellt, dass ich zumindest bei Digital Ocean Spaces manchmal einige Wiederholungen durchführen muss, bevor eine Migration erfolgreich ist. Das aktuelle Skript gibt dir in diesem Fall keine Warnung aus; du musst es einfach weiterhin ausführen und abwarten, ob es klappt. Ich habe jedoch einen Pull Request (PR) eingereicht, der in dieser Hinsicht Fehlermeldungen ausgibt, damit du zumindest weißt, wenn etwas schiefgelaufen ist.

Ich habe eine einfache kurze Wiederholungsschleife sowie die Fehlermeldung hinzugefügt, und es scheint, dass die Wiederholungsschleife das Problem löst. Außerdem wurde die Validierung gemäß den aktuellen Regeln bisher auf den Rohinhalt vergangener Beiträge angewendet, was die Migration unterbrechen und Beiträge, die neu gerendert werden mussten, stillschweigend unberührt lassen konnte; auch das habe ich behoben. Du solltest auf keinen Fall eine Migration durchführen, ohne mindestens die Validierungskorrektur zu erhalten, die einer der Commits in meinem derzeit zur Prüfung stehenden PR ist.

Meine Migration ist, soweit ich weiß, abgeschlossen. Mein PR enthält den gesamten Code, den ich für den Abschluss meiner Migration verwendet habe. Er wurde noch nicht geprüft. Falls du möchtest, empfehle ich dir, unter Migrate_from_s3 problems mitzuverfolgen.

Danke! Ich werde das in den nächsten Tagen ausprobieren.

Ich habe gerade einen Hinweis in diesem Beitrag hinzugefügt, dass noch ein Fehler besteht, den wir heute entdeckt haben: Bei einigen Nutzern fehlen die Profilbilder. Ich weiß nicht, warum das passiert ist. Wir haben es mit einem Schulterzucken abgetan und bitten die betroffenen Nutzer, eine Wiederherstellung vorzunehmen, entschuldigen uns aber für das Problem.

Ich habe während dieses Vorgangs definitiv häufige Sicherungen durchgeführt! :smiling_face:

Viel Erfolg!

Ernsthaft, könnte mich das noch verrückter machen? :crazy_face:

Hier ist, was ich gemacht habe:

  1. Ich habe deinen neuen Code lib/tasks/upload.rake in mein Discourse kopiert.
  2. Ich habe ALLE meine Amazon s3_-Variablen zu config/discourse.conf hinzugefügt.
  3. Ich habe sie auch zu app.yml hinzugefügt (unklar, ob das etwas bringt, aber warum nicht).
  4. Ich habe diesen Befehl ausgeführt und bekam…
root@:/var/www/discourse/config# rake uploads:batch_migrate_from_s3[100,1000]
You must disable S3 uploads before running that task.

Und habe bestätigt:

Also, okay. Ich habe die Datei uploads.rake bearbeitet und einfach diese Prüfung entfernt.

Jetzt bekomme ich:

root@:/var/www/discourse/lib/tasks# rake uploads:batch_migrate_from_s3[100,1000]
Migrating uploads from S3 to local storage for 'default'...
Migrating up to 100 of 1000 posts...
... (viele Ausgaben hier) ...
Modified 91/100: 28795: 28486/1 - https://example.com/t/topic-title-here/28486/1
... (viele Ausgaben hier) ...

Es schien also zu funktionieren! Juhu!

Nachdem der erste Batch von 100 erledigt war, habe ich Sidekiq geprüft und sah, dass mein Testbeitrag in die Warteschlange gestellt wurde, also habe ich gewartet, bis das abgeschlossen war…

…bin dann zurückgegangen und habe nachgeprüft… und dieser Beitrag zieht sein Bild immer noch von Amazon S3. :frowning: Ich habe “HTML neu erstellen” für den Beitrag versucht, aber das hat nichts geändert.

Dann habe ich den gesamten Prozess erneut durchlaufen, von rake bis zum Ende, und bekam die gleichen Ergebnisse – die gleichen 100 Beiträge wurden verarbeitet, die gleichen Dinge in Sidekiq in die Warteschlange gestellt, und nachdem ich es laufen ließ, kommt das Bild in diesem Testbeitrag immer noch von S3.

Hmm, ich bin mir nicht sicher, was ich als Nächstes versuchen soll. :man_shrugging:t2:

@mcdanlj, ich wäre für jeden Vorschlag oder Rat dankbar, den du hast :wink:

Das ist genau das, was ich erwarten würde, wenn Sie diese Prüfung entfernen. Ich bin mir nicht sicher, warum Sie sich entschieden haben, sie zu entfernen. Es ist absichtlich. Schalten Sie vor Beginn der Migration die Uploads nach S3 ab.

Sie waren aus – völlig aus. (Das Bild des Kontrollkästchens in meinem Beitrag ist die richtige Einstellung, oder?) Ich habe sie sogar ein- und wieder ausgeschaltet. Keine Reaktion.