セルフホストへの移行: 過去のアップロードが引き続きディスコースインフラを参照

Checked: Images lost when migrating to self-hosting, posts:rebake does not do anything good.

問題
公式の手順に従い、Lightsailインスタンスを作成しました。そこからDiscourse UIでデータベースをダウンロードし、適用して80%完了しました。目的は、以前のインスタンスを稼働させたまま、セルフホストインスタンスに移行することでした。

古いフォーラムのライブコピーを入手したら、画像の移行を開始します。そのために、まずサブスクリプションをキャンセルして画像を移行します。

セルフホストインスタンスに新しい画像がアップロードされると、移行日より前のホストインスタンスからのみアップロードする必要があります。これは、移行が完了していたため、画像とキャンセルに含まれていたデータベースダンプを使用しなかったことを意味します。

この時点に関連する3つの動作を観察しています。

  1. バックアップ(特にSQLダンプ)内の参照リソースは、Discourseインフラストラクチャを指しています。
  2. バックアップで作成された参照リソース(例:新しい投稿の画像)は、インフラストラクチャで正しく参照され、見つかります。

その結果、同じハッシュ値になるリソースを再アップロードすると、Discourseインフラストラクチャにリンクされます。たとえば、ファビコンを修正するために同じものをアップロードしようとしても機能しません。ただし、ランダムな画像をアップロードすると機能します。

現在の状態
理解している限りでは、upload://<X> はb62デコード(およびsha1?)ビットを経て、public/uploads のフォルダにマッピングされます。これらの画像はすべて持っています。

Discourseチームから提供されたダンプには、default/original/1X を含むzipが含まれており、これは現在 /var/www/discourse/public/uploads/default/original/1X で確認できます。後者のフォルダには現在329個のアイテムが含まれており、提供されたダンプには249個のアイテムが含まれていました。これは良い兆候だと思います。

これは、フォルダ内でアップロードを直接見つけることができなくても、データは検出可能であるはずであることを意味します。この関連性を理解して、マッピングを修正する方法を見つけたいと思っています。当初は単純な文字列置換のように見え、一部の画像では機能しました。しかし、一部の画像は、以前はアクセス不能な画像だったものが、透明な.pngに置き換えられています。

リベイクに失敗した場合は、remap を使用して、Discourse インフラストラクチャへのすべての参照を検索/置換し、相対リンクに置き換える必要があります。

リチャードさん、ありがとうございます!

以下のリンクで説明されている方法で、

以下のように使用します。

rake posts:remap["検索文字列","置換文字列","文字列",true]

以下のように実行します。

rake posts:remap[
  "https://cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/",
  "/uploads/default/"
]

相対パスの代替として、「https://forum.everviz.com/uploads/default/」を使用することもできます。

相対リンクについてお考えのことですか?

e: 相対URLの修正(/付き)

ワンライナー:

rake posts:remap["https://cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/", "/uploads/default/"]

これでいいと思います! スラッシュを前に付ける必要があります

/uploads/default/

ホストされているサイトからバックアップを取得する際に、「すべてのアップロードを含める」にチェックを入れましたか?CDCKでホストされていた場合、すべてのアップロードを含めてバックアップを取得する前に有効にする必要がある隠し設定がありました。現在それが変更されたかどうかはわかりませんが、完全なバックアップ(SQLダンプだけでなく)を取得するために、移動する前に必ずホスティングプロバイダーと連携することをお勧めします。

ホスティングプロバイダーはDiscourseで、月額プランを利用していました。ホストされたユーザーインターフェースには、アップロードされたファイルを取得するためにteam@discourse.comに連絡するように記載されています。彼らの返答は、ファイルを取得するにはサブスクリプションをキャンセルする必要があるとのことでした。

しかし、はい、言及したように uploads/original/1X を受け取りました。

それは良いヒントですが、すでに実行した可能性があります。

root@...:/var/www/discourse$ rake posts:remap["//cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/","/uploads/default/"]
'//cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/' のすべての文字列出現を '/uploads/default/' に置き換えますか? (Y/n)
Y
Remapping
0 posts remapped!

以前は、ホストされているフォーラムでリンクが https://europe1.discourse-cdn.com/standard21/uploads/everviz/ でした。これはもちろん同じものですが、CDN を介してゲートされています。再マッピングを試してみましょう。

1 post remapped.

この画像は興味深いと思います。

もちろん、これは今日のすべてのコマンドを実行する前、およびここに投稿する前でした。いくつかの rake タスクなどを実行する前に、Discourse チームに送信されました。

それをしましたか?彼らは、S3から画像をダウンロードしてバックアップに含めるための隠し設定を有効にする必要があります。通常のバックアップには画像は含まれず、S3バケットへのリンクのみが含まれます。サブスクリプションをキャンセルすると自動的にそれがトリガーされると思いますが、クライアントの中には、単に依頼することで設定を有効にしてもらった人もいます。サブスクリプションをキャンセルするか、もう一度依頼してください。

その方法でやりたくない場合は、S3から画像をダウンロードして、それに応じてDiscourseデータベースを更新するスクリプトを作成する必要があります。

キャンセルしてファイルを受け取りました。ただし、元のDiscourseデータベースのバックアップはS3のパスを参照しているようです。基本的に、/var/www/discourse/uploads/original/1X に必要なものはすべて揃っています。

インスタンスにデータを投入するために、提供されたファイルに含まれるものではなく、手動でダウンロードしたSQLダンプを使用しました。後者には画像の修正されたパスが含まれているのではないかと心配していましたが、それは事実ではないことを確認しました。

例を示すために:


![](upload://3Qa5S9sUTcc42dT4EFAbz5K0iJP.gif) = 1aec065017da50538fe5866ae91a6396185234e1.gif

https://forum.everviz.com/uploads/default/original/1X/1aec065017da50538fe5866ae91a6396185234e1.gif

http://cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/original/1X/1aec065017da50538fe5866ae91a6396185234e1.gif

<img src="https://forum.everviz.com/images/transparent.png" alt="" data-orig-src="upload://3Qa5S9sUTcc42dT4EFAbz5K0iJP.gif" role="presentation" width="1" height="1" style="aspect-ratio: 1 / 1;" loading="lazy">

上記は特殊なケースで、以前のcdck…への参照は単なるtransparent.pngです。それでも、リンクを開けば存在することがわかります。

ですから、問題が発生すると予想していました。

あなたが含めたと思われるraw投稿で、ファイルに付属しているデータベースを使用した場合、![](upload://3Qa5S9sUTcc42dT4EFAbz5K0iJP.gif)はローカルストレージを参照すると予想されますが、誰かがバケット上の画像へのリンクを明示的に貼り付けた場合、修正が必要になるでしょう。画像が存在し、ダウンロード・トゥ・ローカル設定がオンになっている場合、バケットからの画像はダウンロードされます(設定基準を満たしていれば)。

最後の<img>がどのように生成されたのか、よくわかりません。

ローカルへのダウンロードが有効になっています。

リンクされたファイルの場合、「公式」のグッドバイダンプには相対パスが含まれていません。

<img src="https://europe1.discourse-cdn.com/standard21/uploads/everviz/original/1X/1aec065017da50538fe5866ae91a6396185234e1.gif" alt="" data-base62-sha1="3Qa5S9sUTcc42dT4EFAbz5K0iJP" ...

この正確なファイル参照は、一部の場所でcdck…も指しています。

私には少し狂っているように聞こえますが、今バックアップを取ることができます。そして、ダンプファイル自体でローカルパスへのDiscourseインフラへの参照を破棄し、それを再アップロードします。

最後のファイルは、投稿を再調理したため、ソースファイルがDiscourseインフラで検出できなくなったため、transparent.pngを参照している可能性があります。データの完全な損失を見ているとは思いません。

サイトが公開されている場合、Railsで可能な限り修正するだけです。

しかし、その<img>は調理済みの投稿ですよね?生の投稿ではありませんか?

データベースダンプからの画像です。調理済みと推測されます。生の投稿は b62 を upload:// として参照しています。

現在の調理済みは次のとおりです。

<img src="https://forum.everviz.com/images/transparent.png" alt="" data-orig-src="upload://3Qa5S9sUTcc42dT4EFAbz5K0iJP.gif" ...

これまでのところ、rake を使用して missing_uploads を検索および修正したり、投稿を再マッピングおよび再ベイクしたりすることはあまり成功していません。

Jay、ご協力ありがとうございました!

調理済みの投稿で参照されているファイルは機能します。それには問題ありません。

データベースダンプの調理済み投稿を検索している場合は、間違った場所を見ています。

ライブサイトができたので、そこから作業する必要があります。

生の投稿で何が見えますか?その投稿を再ベイクした後、調理済みの投稿で予期しないものは何が表示されますか?

具体的に何をしたのか、投稿(生と調理済み)に何が含まれているのかがわからないと、あまり助けになりません。データが正しくないことが予想されるデータベースから始めたため、このトピックは他の人には役立たないでしょう。

みんなにやめろと言われたことをしてしまいました。データベースとそのダンプファイルに手を加えたのです。現在、ほとんどのことは機能していますが、一部のケースで問題が発生しています。

<img src="https://forum.everviz.com/images/transparent.png"
alt="image" data-orig-src="upload://npqpp5O0wbL89nR9OXtP7Btu4hc.png"
width="517" height="90" style="aspect-ratio: 517 / 90;" loading="lazy">

base62を計算して、その16進数を求めましょう。

npqpp5O0wbL89nR9OXtP7Btu4hc = 0x a411c90267cafca7a1cbcd7c8f4f9b8db17e51ba

次に、/var/www/discourse/public/uploads から find で探してみましょう。

find . -name '*a411c90267cafca7a1cbcd7c8f4f9b8db17e51ba*'
./default/original/1X/a411c90267cafca7a1cbcd7c8f4f9b8db17e51ba.png

ありました!


しかし、なぜ投稿では transparent.png になっているのでしょうか? rake uploads:recover_from_tombstonerake posts:rebake を実行しました。


どうしてこうなったのか?

データベースの uploads カラムで、url テーブルに画像ソースURLの一部として cdck が表示されたままでした。コンテナ内からデータベースにアクセスしました。

postgres psql discourse

そして

UPDATE uploads
SET url = REPLACE(
           url,
           '//cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/',
           '/uploads/default/'
         )
WHERE url LIKE '//cdck-file-uploads-europe1.s3.dualstack.eu-west-1.amazonaws.com/standard21/uploads/everviz/%';

これにより、ほとんどの元の画像やサムネイルが再表示され、有望な結果が得られました。

さらに一歩進んで:ダンプファイルの修正

Discourse はステートレス*であり、私たちが気にかける必要があるのはデータベース内のものだけであるという仮定です。私はこれらのタスクやRuby、Discourseの内部構造にあまり詳しくないので、rakeタスクやRubyをいじる気にはなれませんでした。ただ結果を早く得たかったのです。

*画像を含む public フォルダのことはさておき、必要なものはすべて揃っていることを確認できます。

そこで、UIからデータベースのコピーをダウンロードし、VSCodeで開き、cdck(バケット)参照とeurope1(CDNのバケット)参照を段階的に置換します。

段階的に置換するとは、インスタンスによっては //... と表示され、他のインスタンスでは https:// と表示される場合があるということです。そのため、まず //... を一致させて置換しないと、ファイル全体に末尾の https: が残ってしまいます。

その後、修正したダンプファイルを再アップロードします。このすべてを難しくした要因の一つは、base62のステップであり、生の表現から実際の画像URLへの変換を少し難しくしています。

タスク完了

uploadsテーブルのサイズを再確認したところ、数百件のエントリが不足していることに気づきました。どのステップで失われたのかは不明です。一時テーブルから基本的なSQL JOINを使用して、過去のデータベースバックアップとマージしました。

上記で言及したように、画像に対してリクエストされるURLは、uploadsテーブルのurl列に格納されているものです。railsコンソールから、uploadsテーブルに対してSQLを使用して、これらのCDN参照をローカルドメインに再マッピングしました。

なぜrakeタスクを使用しないのか

おそらく、いくつか有効なものがあり、それらを組み合わせれば機能するものもあるでしょう。しかし、現在の動作を観察でき、何をしたいのか、そしてどのようにすればそれが実現できるのかがわかっている場合—その制限は恣意的だと感じます。

Discourseチームとボランティアの皆様に感謝いたします。皆様から、最終的にいくつかのステップで構成される解決策を発見するために必要な情報をすべていただきました。

「いいね!」 1

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.