1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PleromaでVultrのオブジェクトストレージ使う

Last updated at Posted at 2021-11-15

なぜ

私のインスタンスは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は各自の設定したバケット名で置き換え

pleroma-media_policy
{
  "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
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; }
}

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]の中に

/etc/systemd/system/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は各自の値で置き換え

prod.secret.exs
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

Screen Shot 2022-08-29 at 22.36.46.png

転送が終われば多分普段通りにPleromaが使えるようになってるはずです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?