Mastodonのメディアの保存場所をAmazon S3に移しました。
メディアを自宅鯖に置いた時の悩み
運営しているとメディアの容量が増えていきます。
利用人数が少ないのでそんな容量はありませんが、それでも自宅にメディア置いてるといくつかの悩みが…。
まずVMの容量の肥大化。
リモート含めて画像を溜め込んでいくと運営すればするほどVMも肥大化していく。
自宅鯖だから容量は比較的容易に拡張できるとはいえあんまりでかくしたくない…。
次にバックアップ。
物理故障時にデータが消失するので、自宅でバックアップは必須。
基本的に自宅鯖のデータはRAID1のNASとOneDriveにバックアップしています。
メディアは数十GBあるため、バックアップとか同期がちょっと大変…。
あと故障して書き戻すときとか、容量がでかい故にコピーに時間がかかるのがつらい。
そして自宅からのメディア配信速度。
自宅鯖の固定IPはPPPoEなので混雑する時間帯は多分遅い。
場合によっては帯域制限かかることもあるので制限がかかると多分死ぬほど遅い。
実際、遅いなぁと感じたことはあんまりないですが早いほうがいいよね?
解決策
- メディアをクラウドのオブジェクトストレージに移す
クラウド上のオブジェクトストレージなら容量不足とかの心配がない。
障害でデータ消失なんてことはほぼないだろうけど自宅鯖でデータが消える確率よりは低いだろう。 - CDNを利用する
エッジサーバーからの配信になるので速くなる…はず。
ついでに自宅鯖の帯域制限とか負荷とかそういうのも低減される。
オブジェクトストレージの選択
これはあんまり悩まず決めた。
AWSでRoute53使ってるし、同じAWSなら連携もできるしS3でいいかなと。
料金もそこまでかからんだろうと深く考えてませんが、あまりにかかるようなら再考します。
CDNの選択
これもオブジェクトストレージと同様、AWSで連携したかったのでCloudFront一択。
AmazonS3へのデータ移行
バケットを作って、AWS CLIでファイルのアップロード。
aws configureで設定して、syncでアップロードするだけ。簡単ですね。
aws s3 sync [ローカルファイルのディレクトリ] s3://[バケット名]
移行作業中も更新されてしまうので切り替え直後も一応実行しました。
それと移行前にできるだけ容量をへらすためにtootctl media remove
を実行しました。
CloudFrontの設定
今までメディアはifrit.gaia.ff14-mstdn.xyz/media/の下だったのですが、メディアは専用のサブドメイン(media.ff14-mstdn.xyz)を使うことにします。
証明書のアップロード
公式の手順で証明書をアップロードします。
CloudFrontで使うには、注記にある通り--path
オプションを使用する必要があります。
ディストリビューションの作成
Management ConsoleのCloudFrontの[Create Distribution]ボタンをクリックします。

Webの[Get Started]をクリック。
RTMPとういのもありますが、動画のストリーミング配信とかで使うようです。
次のページで各項目を設定していきます。
OriginSettings
・Origin Domain Name
オリジンのドメイン名。
クリックすると作成したS3バケットが選択可能になっているので選択します。
・Origin ID
自動で設定される。
・Restrict Bucket Access
CroudFront経由以外でのバケットへの直接アクセスを拒否するにはYesにします。
直接アクセスは転送料金とかもあるのでYesにしました。
[
Default Cache Behavior Settings
・Viewer Protocol Policy
[Redirect HTTP to HTTPS]を選択。
Distribution Settings
・Alternate Domain Names
CNAMEを設定するドメインを入力します。
自分の場合は[media.ff14-mstdn.xyz]
・SSL Certificate
[Custom SSL Certificate]を選択して、自分で取得した証明書を使用します。
CNAMEの設定
CloudFrontがAWSなのでCNAMEではなくALIASの設定にしています。
Aレコードでエイリアスを[はい]にすると、エイリアス先でCloudFrontのディストリビューションが直接選択できます。

Mastodonの設定と切り替え
.env.productionにS3用の設定項目があるので埋めるだけ。
Mastodon再起動後に反映されます。
S3_ENABLED=true
S3_BUCKET=[バケット名]
AWS_ACCESS_KEY_ID=******************
AWS_SECRET_ACCESS_KEY==******************
S3_REGION=ap-northeast-1
S3_PROTOCOL=https
S3_ALIAS_HOST=media.ff14-mstdn.xyz