S3バケット名変更後、古い投稿を再ベイクしても新しいS3 CDN URLは取得されません

Discourse のインストール(2.7.0.beta1)と古い Google Groups の投稿のインポート後、S3 バケット/キーの設定(CDN URL は未設定)を追加し、以下のコマンドを実行しました。

rake uploads:migrate_to_s3

これは順調に進んでいるように見えました。すべての画像が S3 にアップロードされ、Discourse は自動的に生成された S3 URL(例:https://ortus-discourse.s3.dualstack.us-west-2.amazonaws.com/original/1X/75747ca17a3ca01f298f836691e1990916bafccb.png)を通じて画像にアクセスしようとしていました。

その後、バケット名を ortus-discourse-uploads に変更し、その前面に CloudFront 配信を設定しました。また、Cloudflare で設定された CNAME https://communitycdn.ortussolutions.com/ も使用しています。

CNAME、CloudFront、S3 はいずれも正常に動作しています。以下のような URL は、バケット内の画像を正しく提供しています。

https://communitycdn.ortussolutions.com/original/1X/75747ca17a3ca01f298f836691e1990916bafccb.png

しかし、問題は Discourse が完全に古い ortus-discourse.s3.dualstack.us-west-2.amazonaws.com ドメインに固定されており(バケット名変更によりこのドメインは機能しません)、コンテナを再構築したり古い投稿を再焼き直ししたりしても、Discourse が新しい CDN URL を使用するようにすることが全くできないことです。この件について 1 日 Google で検索し、app コンテナ内でおそらく 12 回以上再焼き直しを行いましたが、様々な設定を試しても効果はありませんでした。フォーラムの各スレッドでは「再構築と再焼き直し」という同じアドバイスが繰り返されていますが、それでは機能しません。

投稿内の画像が壊れているだけでなく、\u003clink rel="icon" type="image/png" href=""\u003e やサイトロゴさえも古いドメインに固定されており、S3 CDN URL を使用しようとしません。

現在の S3 設定は以下の通りです。

  DISCOURSE_S3_ACCESS_KEY_ID: '********'
  DISCOURSE_S3_SECRET_ACCESS_KEY: '******'
  DISCOURSE_BACKUP_LOCATION: 's3'
  DISCOURSE_ENABLE_S3_UPLOADS: true
  DISCOURSE_S3_BUCKET: 'ortus-discourse-uploads'
  DISCOURSE_S3_UPLOAD_BUCKET: 'ortus-discourse-uploads'
  DISCOURSE_S3_BACKUP_BUCKET: 'ortus-discourse-backups'
  DISCOURSE_S3_REGION: 'us-west-2'
  DISCOURSE_S3_CDN_URL: https://communitycdn.ortussolutions.com

  DISCOURSE_CDN_URL: https://community.ortussolutions.com

投稿内の古い URL を新しい URL にマッピングする試みも以下の通り行いました。

rake posts:remap["ortus-discourse.s3.dualstack.us-west-2.amazonaws.com","communitycdn.ortussolutions.com"]

しかし、このコマンドは「0 件の投稿に影響なし」と報告しました。

環境変数や DB 設定のどこにも、古いバケット名 ortus-discourse を参照する記述はありません。Discourse がその情報をどこから取得しているのか全く分かりません。Discourse は初心者であり、Ruby 開発者でもないため、app.yml、管理 UI、フォーラムで見つけた rake コマンドの出力結果を確認する範囲を超えて調査していません。

Uploads テーブルにあるアップロードの値は何ですか?

./launcher enter app
rails c
Upload.all.sample(10).pluck(:url)

@Falco ご返信ありがとうございます。そのコマンドの出力結果は以下の通りです。

root@discourse-app:/var/www/discourse# rails c
Upload.all.sample(10).pluck(:url)
[1] pry(main)> Upload.all.sample(10).pluck(:url)
=> ["//ortus-discourse.s3.dualstack.us-west-2.amazonaws.com/original/1X/52b3aff4e63a7e38bef42d469bafd1ed7c1cc1a2.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/9f90374a280a4681332bcd2191b8de43462f8776.png",
 "//ortus-discourse.s3.dualstack.us-west-2.amazonaws.com/original/1X/29691fba566fc998a966aa93859753e3cf0b8528.cfc",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/6ae912ced40d60adc1356c1d7acf144b0fa0985a.jpeg",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/4dfe5b48fc8cb5d79880d70355c34d7ed02be812.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/897c4b4e755c1c8e93224a27187dc631a02e4388.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/59886f322e6834b567d473138108fab6e0f33764.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/e3e3429d63155cf0d850e161846d187bc6f273ea.jpeg",
 "//ortus-discourse.s3.dualstack.us-west-2.amazonaws.com/original/1X/1b701869b4b235daa8d6a9a7728766f3b4e69814.txt",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/c83aaee941462d47ef91f0c6448257d07487b231.png"]
[2] pry(main)>

確かに、古いバケットに関連するファイルがいくつかあります。

必要なリマップは以下の通りです:

./launcher enter app
rails c
DbHelper.remap("ortus-discourse.s3.dualstack.us-west-2.amazonaws.com", "ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com")

この操作は取り消せないため、事前にバックアップを取得してください。

@Falco ありがとうございます。2 つのリマップを実行しました。

DbHelper.remap("ortus-discourse.s3.dualstack.us-west-2.amazonaws.com", "communitycdn.ortussolutions.com")
DbHelper.remap("ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com", "communitycdn.ortussolutions.com")

イメージを再ビルドしたところ、サイトヘッダーのロゴなどの問題は解決しました。投稿画像の修正を試みるため、すべての投稿を再ビルド中ですが、時間がかかる見込みです。


再ビルドを待つ間、ここで何が間違っていたのでしょうか?これは Discourse のバグで、アップロードが古い URL に固定され、新しいものに変更されなかったのでしょうか?

CDN URL の変更について言及しているこのような投稿を読みました。しかし、それらは投稿内の文字列を置換するだけ(それは機能しませんでした)としか言及しておらず、DBUtil のリマップについては全く触れていませんでした。How do I change the legacy CDN URLs of images in posts?

S3 へのインポート用 rake スクリプトを再実行しようとしたこともありますが、エラーが発生しました(申し訳ありませんが、その時のエラー内容はメモしていませんでした)。

さらに、最初からやり直すために migrate_from_s3 という rake スクリプトをほぼ実行しようとしたのですが、こちらのフォーラム投稿で、それを実行するとデータベースが壊れてしまうという記載があったため、実行を見送りました。

自分が何を間違えていたのか、あるいはどのフォーラム投稿がこれを解決してくれたのか、全く見当が付きません。(ここに投稿する前に、本当に自力で解決しようと必死に努力しました!)

残念ながら、再ビルドしても投稿に埋め込まれた画像の問題は解決していないようです。興味深いことに、古い投稿を編集すると、以下のような形式で画像が表示されます。

![COMMANDBOXERROR.png|1169x984](upload://yTDVQSa4wbIeLGEZvE7muXe8sAJ.png)

しかし、投稿を表示すると、投稿内に大きな空白があり、それが以下の URL を指しています。

https://community.ortussolutions.com/images/transparent.png

これは比較的新しい変更です。昨日の大部分では、これらの画像は単に古い誤った S3 URL を指していましたが、昨夜か今日のある時点で、透明な PNG が表示されるようになりました。

ふむふむ、それは私が返信で指示した内容とは異なりますね :face_with_raised_eyebrow:

uploads テーブルには S3 の場所を格納するものであり、CDN への置換は Markdown の cook プロセスでのみ行われます。

CDN の URL を uploads テーブルに直接入れてしまっていますが、これはソフトウェアの通常の動作とは異なります。

申し訳ありません。私がクラウドフレアの配信について言及し、実際の URL に合うように調整が必要だと書いたのを、OP を十分に読み飛ばしてしまったのだと勝手に思い込んでいました。望ましくない URL がデータベースのどこかに保存されているとは気づいていませんでした。まずそれがご意図だったのか確認しようかと返信しかけましたが、やるべきことは明白だと感じていました。

ご心配なく、それらを S3 URL に簡単に再マッピングできます。これは新しい Discourse のインストールで、アップロードされたコンテンツはすべて同じ場所にあるため、切り替えは簡単です。

前の投稿で何が間違っていたかについての私の質問は、依然として有効です。

これは単に、オブジェクトストレージのバケットを変更する機能を提供していないことが原因だと考えられます。

ここでいう「サポート」とは、バケットを変更しても正常に動作するとは限らず、そのための公式ガイドや事前パッケージ化された rake タスクも存在しないことを意味します。したがって、バケットを変更する必要がある場合は、データベースの調整が必要になります。

なるほど、それは仕方ありませんね。私がやったことで大きな問題となったのは、S3 バケットの名前を変更し、管理画面でバケット名を更新すればすべてが解決すると勘違いしたことでした。おそらく、管理 UI でバケット名を編集する際に警告が表示されるようにすれば、ここで役立つでしょう。(環境変数を使用する前に、管理 UI の設定から始めたのですが、それが何か助けになるかと思ったためです)バケット名を変更するとアップロード後に問題になることは、確かに明確ではありませんでした。

ドメインを正しい AWS S3 ドメインに再マッピングしました。

DbHelper.remap("communitycdn.ortussolutions.com", "ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com")
[1] pry(main)> Upload.all.sample(10).pluck(:url)
=> ["//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/fc05f9be9b783479819fec68b1d8e493110007a4.cfc",
 "/images/d-logo-sketch-small.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/50f0d6f260cdb4ef91e29023d92b46df096ab34e.cfc",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/65d80cddc6dc15b9a4d1b9e9d88cc9a8928c5316.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/a86aa2a12183428f3289caa95787ea16f22e2e4d.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/9f76b5238b147a60c8ad5f65bd7fa4bb6b58d852.png",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/6a4c9b992e6cd8a15ddeaec0d158ebd473164525.zip",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/3a532dec6390d5087ed6154fc0335c2c0f1ea543.zip",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/93420848249ecea2261d405e46f7f450cc02a3af.txt",
 "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/d67c39e06ce624b9deb7625dd041d21cffd96df9.png"]

アプリを再度ビルドし、現在投稿を再構築しています。37 回目の挑戦が成功するか見てみましょう :slight_smile:

すべてのアップロードが正しい S3 バケット URL を持ち、コンテナが再構築され、30,000 件の投稿すべてが再ビルドされました。しかし、依然としてすべての画像の代わりに以下が表示されています。

/images/transparent.png

投稿を編集しても、以下のように表示されたままです。

![COMMANDBOXERROR.png|1169x984](upload://yTDVQSa4wbIeLGEZvE7muXe8sAJ.png)

興味深いことに、zip ファイルなどの他の添付ファイルは現在正常に動作しています。

過去の投稿に埋め込まれた画像を動作させるために、何か見落としている設定などがありますでしょうか?

yTDVQSa4wbIeLGEZvE7muXe8sAJ に対応する Upload オブジェクトの属性を出力できますか?

ぜひお手伝いしたいのですが、今回は少しサポートが必要です。私は開発者ですが、Ruby 開発者ではありません。以下の方法で、ランダムなアップロードのすべての属性を出力する方法はわかりました:

[17] pry(main)> Upload.all.sample(1)
=> [#<Upload:0x00005633230f8af0
  id: 353,
  user_id: 273,
  original_filename: "helloWorldF.zip",
  filesize: 50542,
  width: nil,
  height: nil,
  url: "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/3a532dec6390d5087ed6154fc0335c2c0f1ea543.zip",
  created_at: Wed, 30 Dec 2020 18:46:31 UTC +00:00,
  updated_at: Wed, 30 Dec 2020 18:46:31 UTC +00:00,
  sha1: "3a532dec6390d5087ed6154fc0335c2c0f1ea543",
  origin: nil,
  retain_hours: nil,
  extension: "zip",
  thumbnail_width: nil,
  thumbnail_height: nil,
  etag: nil,
  secure: false,
  access_control_post_id: nil,
  original_sha1: nil,
  animated: nil,
  verification_status: 1>]

また、特定のレコードを検索するための Rails の Active Record のリファレンスも見つけましたが、yTDVQSa4wbIeLGEZvE7muXe8sAJ に似たデータは見当たりません。対応するアップロードレコードをどのようにして見つけることができますか?

おっと、良いニュースです。アップロード記録の検索方法を調べている際に、base62 文字列を SHA1 ハッシュに変換する方法を示すこの投稿を見つけました。

そこには、単に transparent.png が表示されている画像が「tombstoned(墓碑化)」されたという記述がありました。その意味は完全にはわかりませんが、画像が破損している間に夜間プロセスが実行され、それらが未使用としてマークされたのだと思います。私は以下のコマンドを実行できました。

rake uploads:recover_from_tombstone

その結果、埋め込まれていた画像がすべて復元され、現在は私の S3 CDN を指しているようです。

参考までに、yTDVQSa4wbIeLGEZvE7muXe8sAJ という文字列からアップロード記録を特定した手順も共有します。

[14] pry(main)> Base62.decode("yTDVQSa4wbIeLGEZvE7muXe8sAJ").to_s(16)
=> "f49428d6af35d7e0414408ccb65e7316f5003215"
[15] pry(main)> Upload.where( "original_filename ilike '%f49428d6af35d7e0414408ccb65e7316f5003215%'" )
=> [#<Upload:0x000056313aa91fe8
  id: 899,
  user_id: 549,
  original_filename: "f49428d6af35d7e0414408ccb65e7316f5003215.png",
  filesize: 25514,
  width: 1169,
  height: 984,
  url: "//ortus-discourse-uploads.s3.dualstack.us-west-2.amazonaws.com/original/1X/f49428d6af35d7e0414408ccb65e7316f5003215.png",
  created_at: Tue, 12 Jan 2021 23:01:35 UTC +00:00,
  updated_at: Tue, 12 Jan 2021 23:01:36 UTC +00:00,
  sha1: "f49428d6af35d7e0414408ccb65e7316f5003215",
  origin: nil,
  retain_hours: nil,
  extension: "png",
  thumbnail_width: 594,
  thumbnail_height: 500,
  etag: "6977f35ddbf39a4399dc76f92a5079d4",
  secure: false,
  access_control_post_id: nil,
  original_sha1: nil,
  animated: nil,
  verification_status: 1>]

@Falco さん、再びご協力いただきありがとうございます。Discourse は初心者ですが、とても忍耐強く親切に対応していただいております :+1: