@Jite さん、こんにちは!
これでうまくいくか確認してみてください。問題なければ、正式な howto を作成します。
古いバケット
ここでは、ツールをインストール・設定して、古いバケットからローカルマシンへデータを移動し、その後ローカルから新しいバケットへ再度移動できることを前提としています。詳細については、aws cli sync(AWS 以外のバケットでも設定可能)および gsutil rsync を参照してください。データ量が膨大である場合、または同じプロバイダー内のバケット間を移動する場合は、データを直接バケット間で移動する方法を検討してください。
一時保存に適したディレクトリに入ってください(例:mkdir temp-bucket; cd temp-bucket)。その後、以下のような操作を行います。これらの例には、実行内容を確認するための -n および --dry-run オプションが含まれています。意図した通りであれば、そのオプションを外して再度コマンドを実行してください。
古いデータを古いバケットからローカルへ移動
gsutil rsync -r -n gs://=OLD= .
または
aws s3 sync s3://=OLD= .
ローカルから新しいバケットへデータを移動
gsutil rsync -r -n . gs://=NEW=
または
aws s3 sync . s3://=NEW=
データベースを更新して新しいバケットを使用するように設定
これらは Rails コンソールで実行します。コンソールに入るには、以下を実行してください。
cd /var/discourse
./launcher enter app
rails c
新しいバケットの設定で画像をアップロードし、以下のコマンドを実行してください。
Upload.last.url
以下のような結果が表示されるはずです。
=> "//discourse-bucket.s3.dualstack.us-east-2.amazonaws.com/`original/2X/7/12345fbea574afc4e02db80107e6682430aede2c.png"
これで、新しいバケットの discourse-bucket.s3.dualstack.us-east-2.amazonaws.com が取得できます。同様に、上記から古いバケットのホスト名も取得してください。
アップロードが正しい場所にあるか確認するには、以下を使用してください。
Upload.order(Arel.sql('RANDOM()')).limit(10).pluck(:id, :url)
次に、データベースを更新して古いバケットの代わりに新しいバケットを使用するように設定します。DbHelper.remap は、すべてのテーブル内の出現箇所を置換します。
DbHelper.remap("//=OLDHOST=/","//=NEWHOST=/")
AWS への移行には s3_endpoint のクリアが必要な場合があります
注意:データベース内の SiteSettings で s3_endpoint が定義されており、AWS へ移行する場合(AWS ではエンドポイント不要)、設定を更新した新しいコンテナをビルドした後(または、設定が含まれるデータベースをリストアした後)、そのサイト設定をクリアする必要があります。
バケットを指すポストを S3 CDN ではなく S3 CDN として再構築する
新しい S3 バケットに直接リンクするポストがある場合(以前は s3_cdn_url が定義されていなかったなど)、必要なポストのみを再構築する方法を以下に示します。
ポストを取得:
posts=Post.where("cooked like '%=NEWHOST=%'")
件数を確認:
posts.count
該当ポストを再構築:
posts.each do |p| p.rebake! end
または、バケットを CDN に置換するだけです:
posts.each do |p|
p.cooked.gsub!(/=NEWHOST=/,"=CDN=")
p.save!
end