2
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?

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

Last updated at Posted at 2021-11-21

なぜ

私のインスタンスはVultr Cloud Computeで動いているわけですが、Mastodonの方をVultrのオブジェクトストレージに移行したんで
https://qiita.com/atsu1125/items/fc44c2de0ec6ed197669
ついでにPeerTubeも移行してしまおうということです。
これのPleroma編もあります。
https://qiita.com/atsu1125/items/20b7afbccab6bc829fa2

環境

うちは以下のサーバーでPeerTubeのアプリケーションを実行しています。
データベースはまた別なサーバーにあります。
通常1台のサーバーだと思いますのでそれ向けの内容で書きます。
この方法はPeerTubeのバージョンが3.4以降でのみ使えます。
Vultr High Frequency Compute Tokyo Region
CPU 1Core / RAM 2GB / NVMe 64GB
Fedora 35 non Docker
PeerTube 3.4.1
そして今回はオブジェクトストレージのURLをそのまま公開することはせず、PeerTubeをホストしている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で進む

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

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

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

次にCORSポリシーを設定します。
日本語ではオリジン間リソース共有と言いますが、
今回PeerTubeのサーバーとオブジェクトストレージの動画はそれぞれ異なるドメインから提供されますので
これを設定しなければ、セキュリティのために動画が再生されなくなってしまいます。
そのためまずcorsrules.xmlを作成します。
yourdomainは各自のPeerTubeのドメイン名に置き換えてください。

corsrules.xml
<CORSConfiguration>
<CORSRule>
    <ID>Allow WebFont for PeerTube instance</ID>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
</CORSRule>
</CORSConfiguration>

これを保存したら以下のコマンドを実行して反映させます。
yourbacketnameは各自の設定したバケット名で置き換えてください。

s3cmd setcors corsrules.xml s3://yourbacketname

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

オブジェクトストレージのメディアを参照するためのWebサーバーのアドレスをサブドメインとして登録する。
私はGoogle Domainsなのだけど、ここでPeerTubeサーバーと同じアドレスで、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 / {
      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

メディア用プロキシのサブドメインの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秒待って再起動するようにしています。
これでインターネットにつながるまで待つことができるので何回目かの再起動にて正常に起動できます。

PeerTubeの設定ファイルの編集

PeerTubeユーザーに入ったら/www/peertube/config/production.yamlを開いて編集
以下の設定値を反映
yourbacketname, youraccesskey, yoursecretkey, yourdomainは各自の値で置き換え

prod.secret.exs
object_storage:
  enabled: true

  # Without protocol, will default to HTTPS
  endpoint: 'ewr1.vultrobjects.com' # 's3.amazonaws.com' or 's3.fr-par.scw.cloud' for example

  region: 'us-east-1'

  credentials:
    # You can also use AWS_ACCESS_KEY_ID env variable
    access_key_id: 'youraccesskey'
    # You can also use AWS_SECRET_ACCESS_KEY env variable
    secret_access_key: 'yoursecretkey'

  # Maximum amount to upload in one request to object storage
  max_upload_part: 4GB

  streaming_playlists:
    bucket_name: 'yourbacketname'

    # Allows setting all buckets to the same value but with a different prefix
    prefix: 'streaming-playlists/' # Example: 'streaming-playlists:'

    # Base url for object URL generation, scheme and host will be replaced by this URL
    # Useful when you want to use a CDN/external proxy
    base_url: 'https://s3.yourdomain' # Example: 'https://mirror.example.com'

  # Same settings but for webtorrent videos
  videos:
    bucket_name: 'yourbacketname'
    prefix: 'videos/'
    base_url: 'https://s3.yourdomain'

問題なければ、sudoユーザーに戻りsudo systemctl restart peertubeで再起動し設定ファイルを反映
もしエラーが出るならsudo journalctl -u peertube -fなどで内容を確認
またブラウザからPeerTube開いてみて、おそらくこの時点では画像が何も出てこないけど、試しに画像をアップロードして、DMの公開範囲で投稿してみるとその画像だけ見えるようになれば、大丈夫

既存のメディアファイルをオブジェクトストレージにコピー

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

cd /var/www/peertube/peertube-latest
sudo -u peertube NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run create-move-video-storage-job -- --to-object-storage --all-videos

これでローカルからオブジェクトストレージに移動できます。
転送が終われば多分普段通りにPeerTubeが使えるようになってるはずです。

2
1
4

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
2
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?