0
Help us understand the problem. What are the problem?

posted at

updated at

MastodonでVultrのオブジェクトストレージ使う(ローカルから移行するパターン)

なぜ

私のインスタンスはVultr Cloud Computeで動いているわけですが、前回の記事でリモートメディアを定期的に削除してディスク使用量を削減しているものの、削除しすぎて掘り返したい画像がなかったので、今回はMastodonのメディアを全てVultr Object Storageに保管することになりました。
https://qiita.com/atsu1125/items/5c7ce7475cd3e74ad456

環境

うちは以下2台のサーバーでMastodonのアプリケーションを実行しています。
データベースはまた別なサーバーにあります。
通常1台のサーバーだと思いますのでそれ向けの内容で書きます。
Vultr Cloud Compute Tokyo Region RAM 2GB/SSD55GB Fedora 34 non Docker
Vultr Cloud Compute Seoul Region RAM 2GB/SSD55GB Fedora 34 non Docker
そして今回はオブジェクトストレージのURLをそのまま公開することはせず、MastodonをホストしているNginxでリバースプロキシを行います。
そうしないとリージョンが遠くて単純に不利だし、転送量課金なのでなるべくキャッシュして帯域利用量を減らすべきなのです。
またオブジェクトストレージを将来的に廃止した場合や移転した場合は、自分のインスタンス上では設定ファイルの書き換えだけでURLを変更できちゃいますが、リモートインスタンスから見ればその画像を投稿した時点のURLを参照し続けるので、そのURLが消滅した時点で404になってしまいます。
しかしリバースプロキシしておけば、URLを変えずにオブジェクトストレージを変更できますし、最悪廃止した場合でも、そのURLでローカルのファイルを読み出すように設定すれば404になること回避可能です。

VultrのWebからオブジェクトストレージを作成する

Vultrのアカウントにログインしてオブジェクトストレージを追加する。
今はアメリカのニュージャージー州にしか置けない。Labelは適当に。
ReadyになったらCreate Bucketsでバケット作成する。
このバケット名は同一リージョン内で他のユーザのものを含めユニークである(重複しない)必要があるので、
オリジナル性の高い名前(インスタンス名)とかにするといいんじゃないかしら。
バケット作成できたらそのタブは開きっぱなしにして次に。

オブジェクトストレージのポリシーを設定する

Vultrのオブジェクトストレージはデフォルトだと非公開なので公開できるようにする。
以下のコマンドでまずオブジェクトストレージに繋がるようにする。
s3cmdの使い方については https://www.vultr.com/ja/docs/how-to-use-s3cmd-with-vultr-object-storage を見て。

sudo dnf install s3cmd
s3cmd --configure

Access Keyはさっき開きっぱなしにしてたページのAccess Keyを入力
Secret KeyはそのページのSecret Keyを入力
Default RegionはEnter
S3 Endpointはewr1.vultrobjects.comを入力
DNS-styleは%(bucket)s.ewr1.vultrobjects.comを入力
あとはEnter, Enter, Enter, y+Enter, y+Enterで進む

できたら今度mastodon-media_policyってテキストファイルを作成
yourbacketnameは各自の設定したバケット名で置き換え

mastodon-media_policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AddPerm",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::yourbacketname/*"
    }
  ]
}

保存して、s3cmd setpolicy mastodon-media_policy s3://yourbacketnameを実行

ネームサーバーでメディア用プロキシのサブドメインのレコードを作成する

オブジェクトストレージのメディアを参照するためのWebサーバーのアドレスをサブドメインとして登録する。
私はGoogle Domainsなのだけど、ここでMastodonサーバーと同じアドレスで、s3っていうホスト名のサブドメインのAレコード, AAAAレコードを追加する。s3っていうのはawsで使われる名前ではあるけど、s3互換とか言うし短い名前だからいいんじゃないかしら。
ちなみに全然違うドメインにホストしても構わないからね。
misskey.ioだってs3.arkjp.netでメディア用プロキシをホストしてたりするし

メディア用プロキシのトップページを作る

私みたいな物好きがメディア用プロキシのトップページにアクセスしてくるかもしれないので
/home/mastodon/live/public/system/index.htmlを作成して一応参照できるようにしておきました。
こんなの要らないかもしれない。。。

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf8">
    <title>Object Storage</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimal-ui">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.2/css/bulma.min.css">
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
</head>

<body>
    <section class="helo has-background-primary">
        <div class="hero-body">
            <div class="container has-text-centered">
                <h1 class="title is-1">Object Storage</h1>
            </div>
        </div>
    </section>
</body>

    <section class="section">
        <div class="container">

            <h2 class="title is-3">Object Storage?</h2>

            <div class="box">
                <div class="content">
                    <p>Mastodonのメディアを保管するための記憶領域のことです。</p>
                    <p><a href=https://www.vultr.com/ja/products/object-storage>Vultr Object Storage</a>を使用しています。</p>
                </div>
            </div>

        </div>

メディア用プロキシのNginx設定ファイルを作成する

そしたらそのメディア用のプロキシのためのNginxの設定ファイルを書いてくよ
私は/etc/nginx/conf.d/s3.yourdomain.confに設定ファイル書いてるけど
各自の運用に合わせて作成してみて
yourdomainを各自のドメイン名で置き換えるのと
proxy_pass の後のURLはyourbacketnameがバケット名なのでさっき作成したバケット名に置き換える。

s3.yourdomain.conf
server {
  listen 80;
  listen [::]:80;
  server_name s3.yourdomain;
  location /.well-known/acme-challenge/ { allow all; }
  location / { return 301 https://$host$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name s3.yourdomain;
    ssl_session_cache shared:ssl_session_cache:10m;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;

    location / {
      root /home/mastodon/live/public/system;
      try_files $uri $uri/ @proxy;
    }

    location @proxy {
      proxy_ignore_headers set-cookie;
      proxy_hide_header set-cookie;
      proxy_set_header cookie "";
      proxy_hide_header etag;
      resolver 8.8.8.8 valid=100s;
      proxy_pass https://yourbacketname.ewr1.vultrobjects.com$request_uri;
      expires max;
    }
}

これを保存したらsudo nginx -tで設定ファイル確認して大丈夫ならOK

try_filesとか何やってるの?だけど、これは自分のインスタンスで投稿した画像はリモートインスタンスから見たときのURLを変更できないことに起因しています。 そのため原則今までのメディアファイルはオブジェクトストレージにコピーせず削除もせずローカルに保管して、適宜zipとかにしてオブジェクトストレージにバックアップしておいてください。 オブジェクトストレージ設定反映以前の自分のインスタンスのメディアは自分のサーバーから参照していて、オブジェクトストレージの設定反映以降の自分のインスタンスのメディアは、オブジェクトストレージから参照しています。 もちろん工夫次第では従来のURLと新しいURL両方でアクセスするように設定することもできます。

メディア用プロキシのサブドメインのSSL証明書を取得する

先ほどs3っていうホスト名のサブドメイン作ったのでSSL証明書が必要ですね。
今回はcertbotのnginxプラグインで一発で取得しちゃいます。
yourdomainは各自のドメインにしてね。
sudo certbot --nginx -d s3.yourdomain
それで成功したならば、sudo nginx -tで確認してsudo systemctl reload nginxで反映

Mastodonの設定ファイルの編集

いつも通りmastodonユーザーに入ったら.env.productionを開いて編集
以下の設定値を反映
yourbacketname, youraccesskey, yoursecretkey, yourdomainは各自の値で置き換え

.env.production
S3_ENABLED=true
S3_BUCKET=yourbacketname
AWS_ACCESS_KEY_ID=youraccesskey
AWS_SECRET_ACCESS_KEY=yoursecretkey
S3_ENDPOINT=https://ewr1.vultrobjects.com
S3_ALIAS_HOST=s3.yourdomain

問題なければ、sudoユーザーに戻りsudo systemctl restart mastodon-{web,sidekiq,streaming}で再起動し設定ファイルを反映
もしエラーが出るならsudo journalctl -u mastodon-web -fなどで内容を確認
またブラウザからMastodon開いてみて、おそらくこの時点では画像が何も出てこないけど、試しに画像をアップロードして、DMの公開範囲で投稿してみるとその画像だけ見えるようになれば、大丈夫
もし出てこないなら何か間違っているので、手順を見直し、投稿した画像のサムネを右クリックして新しいタブで画像を開くで表示されるURLを確認、これがhttps://s3.yourdomain/media_attachmentsになっているかどうかを見てやる。

既存のメディアキャッシュファイルをオブジェクトストレージに移動

今のままだと見えない画像だらけなのでオブジェクトストレージに移動したい

ここでのよくある間違いとして自分のインスタンスのメディアは移動してはいけません。 なんでかというと自分のインスタンスでは既存の画像を含めてオブジェクトストレージのURLに切り替わりますが、連合先では投稿済みのメディアのURLは切り替えません。 ほとんどのMastodonインスタンスはローカルに画像をキャッシュしているとはいえ、Pleroma,Misskeyインスタンスの場合はキャッシュしていないことが多いです。つまりこの切り替え以前のメディアは一生オブジェクトストレージではなくMastodonのpublic/systemにアクセスして逐一取得します。 そのためローカルのメディアファイルを消すと404出てしまいます。気をつけましょう。

警告はさておき、オブジェクトストレージにコピーしますので、Mastodonユーザーでログインしてください。
ここではaws-cliを使用します。

pip3 install aws-cli

これでインストールできますが多分aws configureしても失敗します。見つからないって言われます。
なのでパスを通すのです。
.bash_profileを編集しましょう

.bash-profile
export PATH="/home/mastodon/.local/bin:${PATH}"

を追加してください。
環境によっては違うところにあるかもしれないのでその場合はpip3を駆使して探しましょう。
パス通ったら
aws configureで先ほどのようにアクセスキー・シークレットキーを入力してEnterで確定します。
できたら以下のコマンドで転送開始です。yourbacketnameは適宜置き換えです。
これ大体ですね、環境によって何時間かかります。やってみないとわからないです。

aws s3 sync /home/mastodon/live/public/system/cache s3://yourbacketname/cache --endpoint-url=https://ewr1.vultrobjects.com

転送が終われば多分普段通りにMastodon使えるようになってるはずです。
あとはローカルのキャッシュを消します。

mv /home/mastodon/live/public/system/cache{,.old}

はい、このコマンドでは消えませんが、消したような扱いにはなります。
これでMastodon開いて正しく画像が表示されてる確認してください。
十分確認して大丈夫なら

rm -r /home/mastodon/live/public/system/cache.old

これである程度開放されたはずです。

繰り返しますがここでのよくある間違いとしてローカルのメディアの削除はしてはいけません。cacheは外部から持ってきたものですが、それ以外は自分のインスタンスにしかないものなので、削除しちゃうとリモートインスタンスから見たときは404エラーになります。 mastodonのpublic/systemを削除するコマンドとか打たないように。 Pleroma, Misskey鯖缶から怒られが発生しますよ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?