なぜ
私のインスタンスはVultr Cloud Computeで動いているわけですが、Mastodonの方をVultrのオブジェクトストレージに移行したんで
https://qiita.com/atsu1125/items/fc44c2de0ec6ed197669
ついでにPleromaも移行してしまおうということです。
環境
うちは以下のサーバーでPleromaのアプリケーションを実行しています。
データベースはまた別なサーバーにあります。
通常1台のサーバーだと思いますのでそれ向けの内容で書きます。
Vultr High Frequency Compute Tokyo Region
CPU 1Core / RAM 2GB / NVMe 64GB
Fedora 36 non Docker
Pleromaのメディアファイルの扱い
今回はオブジェクトストレージのURLをそのまま公開することはせず、PleromaをホストしているNginxでリバースプロキシを行います。
そうしないとリージョンが遠くて単純に不利だし、転送量課金なのでなるべくキャッシュして帯域利用量を減らすべきなのです。
またオブジェクトストレージを将来的に廃止した場合や移転した場合は、自分のインスタンス上では設定ファイルの書き換えだけでURLを変更できちゃいますが、リモートインスタンスから見ればその画像を投稿した時点のURLを参照し続けるので、そのURLが消滅した時点で404になってしまいます。
しかしリバースプロキシしておけば、URLを変えずにオブジェクトストレージを変更できますし、最悪廃止した場合でも、そのURLでローカルのファイルを読み出すように設定すれば404になることを回避可能です。
Pleromaのメディアはオブジェクトストレージを使わない場合はhttps://インスタンスドメイン/media
でプロキシされており、オブジェクトストレージ使用後も引き続き、移行前の画像は連合先からも読むことができます。
Mastodon/Misskeyとは異なる挙動をします。
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で進む
できたら今度pleroma-media_policy
ってテキストファイルを作成
yourbacketnameは各自の設定したバケット名で置き換え
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbacketname/*"
}
]
}
保存して、s3cmd setpolicy pleroma-media_policy s3://yourbacketname
を実行
ネームサーバーでメディア用プロキシのサブドメインのレコードを作成する
オブジェクトストレージのメディアを参照するためのWebサーバーのアドレスをサブドメインとして登録する。
私はGoogle Domainsなのだけど、ここでPleromaサーバーと同じアドレスで、s3っていうホスト名のサブドメインのAレコード, AAAAレコードを追加する。s3っていうのはawsで使われる名前ではあるけど、s3互換とか言うし短い名前だからいいんじゃないかしら。
ちなみに全然違うドメインにホストしても構わないからね。
misskey.ioだってs3.arkjp.netでメディア用プロキシをホストしてたりするし
メディア用プロキシのNginx設定ファイルを作成する
そしたらそのメディア用のプロキシのためのNginxの設定ファイルを書いてくよ
私は/etc/nginx/conf.d/s3.yourdomain.confに設定ファイル書いてるけど
各自の運用に合わせて作成してみて
yourdomainを各自のドメイン名で置き換えるのと
proxy_pass の後のURLはyourbacketnameがバケット名なのでさっき作成したバケット名に置き換える。
max_size=20g
(20GB)の部分は画像のキャッシュを保存する最大容量なので、Nginxを置くサーバーのストレージに余裕がない場合は減らすことを検討する。max_size=256m
(256MB)と書くことも可能
またproxy_cache_path
で保存先を余裕のあるストレージに変えることも可能
mkdir /var/cache/nginx/proxy_cache_images
chown -R nginx: /var/cache/nginx/proxy_cache_images
server {
listen 80;
listen [::]:80;
server_name s3.yourdomain;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
proxy_cache_path /var/cache/nginx/proxy_cache_images levels=1 keys_zone=images:2m max_size=20g inactive=90d;
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 /opt/pleroma/uploads;
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 127.0.0.53 valid=30s ipv6=off;
proxy_pass https://yourbacketname.ewr1.vultrobjects.com$request_uri;
proxy_buffering on;
proxy_cache images;
proxy_cache_valid 200 302 90d;
proxy_cache_valid any 5m;
proxy_ignore_headers Cache-Control Expires;
proxy_cache_lock on;
add_header X-Cache $upstream_cache_status;
}
}
これを保存したらsudo nginx -t
で設定ファイル確認して大丈夫ならOK
try_filesとか何やってるの?だけどこれはもし同じサーバー内に目的のメディアファイルがあればそれを参照して、なければオブジェクトストレージに取りに行くようにしてる。
メディア用プロキシのサブドメインのSSL証明書を取得する
先ほどs3っていうホスト名のサブドメイン作ったのでSSL証明書が必要ですね。
今回はcertbotのnginxプラグインで一発で取得しちゃいます。
yourdomainは各自のドメインにしてね。
sudo certbot --nginx -d s3.yourdomain
それで成功したならば、sudo nginx -t
で確認してsudo systemctl reload nginx
で反映
Nginxのsystemd serviceファイルの編集
Nginxでオブジェクトストレージをプロキシするようにしたのですが、どうやらサーバーを再起動した後にNginxの起動に失敗するようになってしまうケースがあるようです(私がそうだった)
原因としてはNginxがnetwork-online.target
のあとmulti-user.target
で起動するのですが、その際にリンクアップしているもののまだインターネットにつながってないことがあるため、Nginxの起動時にnginx -t
を実行してupstreamに接続できないっていうエラーを出してしまうからです。
対策として
systemctl edit --full nginx.service
でNginxのサービスファイルを開いたら、[Service]
の中に
Restart=always
RestartSec=5
と追記します。
できたらsystemctl status nginx
でエラーが出ていないことを確認してください。
この設定ではNginxのプロセスが何らかの原因で落ちてしまった時に5秒待って再起動するようにしています。
これでインターネットにつながるまで待つことができるので何回目かの再起動にて正常に起動できます。
Pleromaの設定ファイルの編集
sudo -Hu pleroma $SHELL
でPleromaユーザーに入ったら/opt/pleroma/config/prod.secret.exs
を開いて編集
以下の設定値を反映
yourbacketname, youraccesskey, yoursecretkey, yourdomainは各自の値で置き換え
config :pleroma, Pleroma.Upload,
uploader: Pleroma.Uploaders.S3,
base_url: "https://s3.yourdomain"
config :pleroma, Pleroma.Uploaders.S3,
bucket: "yourbacketname",
bucket_namespace: "",
truncated_namespace: "",
streaming_enabled: true
config :ex_aws, :s3,
access_key_id: "youraccesskey",
secret_access_key: "yoursecretkey",
region: "us-east-1",
scheme: "https://"
config :ex_aws, :s3,
host: "ewr1.vultrobjects.com"
問題なければ、MIX_ENV=prod mix compile
でPleromaアプリのコンパイルを完了させてから、sudoユーザーに戻りsudo systemctl restart pleroma
で再起動し設定ファイルを反映
もしエラーが出るならsudo journalctl -u pleroma -f
などで内容を確認
またブラウザからPleroma開いてみて、おそらくこの時点では画像が何も出てこないけど、試しに画像をアップロードして、DMの公開範囲で投稿してみるとその画像だけ見えるようになれば、大丈夫
もし出てこないなら何か間違っているので、手順を見直し、投稿した画像のサムネを右クリックして新しいタブで画像を開く
で表示されるURLを確認、これがhttps://s3.yourdomain/{画像のファイル名をいじったもの}
になっているかどうかを見てやる。
これでこれ以降のメディアファイルへのアクセスはオブジェクトストレージが使用されます。
既存のメディアファイルをオブジェクトストレージにコピー
今のままだと見えない画像だらけなのでオブジェクトストレージにコピーしたい
Pleromaユーザーでログインsudo -Hu pleroma $SHELL
してください。
cd /opt/pleroma
でPleromaのディレクトリに入ります。
https://docs-develop.pleroma.social/backend/administration/CLI_tasks/uploads/
でマイグレーションが可能らしいです。
情報提供ありがとうございます。
MIX_ENV=prod mix pleroma.uploads migrate_local S3
転送が終われば多分普段通りにPleromaが使えるようになってるはずです。