LOG IN

Mastodon v2.4.0 にアップデートしました

by やきたま

Mastodon v2.4.0 が日本時間で 5月23日 にリリースされましたね。私のサーバーでも土曜日のアップデートを予告してアップデートを実施しました。そのときの記録を少しだけ。

これから Mastodon v2.4.0 にアップデートする管理者さんへ

記事を書き始める前に、私のアップデートを振り返ってみることにします。
いくつか「正常に終了しない」アップデート手順がありましたが、そのすべてで何らかのログを確認することができました。手順を実行したときに表示されるメッセージをちゃんと読んで、さらに情報が必要なら Mastodon の journalctl で得られるログも活用するとよいでしょう。残念ながら、「このエラーが出たときにはこうする」というほどは情報が揃っていませんが、エラーメッセージを見逃さないことが、アップデートを成功させるための最初のステップです。

アップデート前には心配していた

実は Mastodon v2.4.0 にアップデートするにあたって、心配事がありました。master 追従インスタンスや rc バージョンを積極的にインストールするインスタンスから、さまざまな "一筋縄では行かなかった" 情報を聞いていたのです。私はまだ Mastodon インスタンスを自分で管理するようになってから半年も経っていない初心者ですから、それはもうビクビクです。

実際にアップデートを始めた

今回はリリースノートの一番最初にデータベースのバックアップを取ってから作業をしてねって書いてありましたよね。"あくまで一般論として" みたいな書き方でしたが、今回は最悪環境をぶっ壊すかもしれないと思っていましたから、バックアップの手順を調べて実施しました。私のサーバーは PostgreSQL 9.5 がインストールされていましたので、こちらのドキュメントを参考に実施しました。ちなみにこのドキュメントには、PostgreSQL バージョンごとのバックアップ方法へのリンクがありますから、みなさんが実施される際にはまずバージョンの確認を。

続いて Ruby と Node.js のアップデートを Bundler で実施します。すると、ここで Ruby 2.5.1 が必要だと言われます。私の環境では 2.5.0 がインストール済でした。こちらは少し手間取りましたが、Mastodon Production Guide の通りにインストール作業を進めているのでしたら、Ruby をインストールするためには rbenv と ruby-build を GitHub から clone してインストールしているはずです(ここ)。なので、rbenv install 2.5.1 とすれば Ruby 2.5.1 がインストールできるはずです。もしこれで「2.5.1 が見当たらない」というようなメッセージを見た場合は、ruby-build のアップデートが必要です。~/.rbenv/plugins/ruby-build/ まで移動し、git pull しましょう。そして再実行すればインストールできます。

次は yarn による依存パッケージ類のインストールです。今度はこちらで、「あなたのネットワーク接続に問題があって、パッケージのダウンロードができません。バグだと思うなら報告してみな」というようなエラーに遭遇します。ダウンロードしようとしているパッケージに、サーバーからではなく手元の環境からもアクセスしてみましたが、たしかにダウンロードできません。……何度かリトライしていると、いつの間にかダウンロードできるようになりました。なんだったんでしょうね。

このあとのデータベーススキーマのマイグレーションとアセットのプリコンパイルは正常に終了しました。普段であれば、ここまでできれば Mastodon のサービスを再起動すればバージョンアップが完了します。

そしてトラブルシューティングへ

今回のアップデートでは画像のアップロード時にクライアント側でリサイズをおこなう機能が追加されました。ですのでこの機能が動作しているかテストしてみます。すると、予想通り動きません。Mastodon v2.4.0 のリリースノートによれば、Content-Security-Policy という HTTP ヘッダを追加していい感じに設定しないといけないようです。困りました、私はこの HTTP ヘッダのことを知りませんし、しかもリリースノートに「いい感じに設定(adjust it)」といきなり突き放されたのです! 
[2018/05/27 16:55追記] 私はここから CSP ヘッダを設定する作業に移りましたが、どうやら "設定しなければ動くはず" のもののようです。以前に CSP ヘッダを設定しておりすでにサーバーが当該 HTTP ヘッダを送信しているのであれば、リリースノートや私の設定を参考に足りないものを許可するように設定すれば動くはずです。もし設定していないのに画像アップロードができないのでしたら、他の原因の可能性がありますから、まずは journalctl あたりで得られるログを確認してみるとよいかもしれません。

この HTTP ヘッダは、画像やスタイルシート、スクリプト、その他さまざまな HTML に埋め込んで使用されるコンテンツの配信ソースを制限するためのもののようです。クロスサイトスクリプティングなどを防ぐ効果があるそうですね。正直なところ調べても調べてもよくわからなかったので、こんな感じに設定しました:
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: blob: https:; media-src 'self' data: blob: https:; connect-src 'self' blob: wss: https:; style-src 'self' 'unsafe-inline'";
「default-src」は、続く様々なコンテンツタイプで指定されなかったその他のコンテンツの配信元を制限するための部分です。今回大切なのは、img-src、media-src、connect-src になります。Mastodon リリースノートによれば、img-src と connect-src に blob: をソースとするコンテンツを許可するように書いてありますが、実際に設定して Mastodon の挙動を確認していると、他にも data: による何らかのデータ取得(w3c がうんぬんとか書いてました)、それから私は Google の Cloud Storage からの画像配信をおこなっていますから、そちらのサーバーをコンテンツ配信元として許可する(https:)がありました。connect-src では、Streaming API を使用するために WebSocket を使用していますから wss: を明示的に指定する必要がありました。また、style-src では、Mastodon がスタイルシートの他にも埋め込みのスタイル(<style>タグのことです)も使用しているらしく、'unsafe-inline' を指定する必要がありました。Mastodon では画像の他に動画も添付することができますから、img-src と同じ制限を media-src にも適用しました。

ここまで設定して画像のアップロードテストを実施すると、今度は HTTP ステータスコード 500 が返ってくるようになりました。nginx のサーバーログを確認してみると、アクセスログには確かに 500 のログが残っており、同時刻のエラーログには a client request body is buffered to a temporary file で始まるログが残ったり残らなかったりしていました。こちらは調べてみると、nginx ではリクエストをメモリ上にバッファする機能があるようですが、大きなファイルのアップロード等でリクエストが大きくなるとメモリに収まらなくなるのでテンポラリファイルを作るという挙動をするようです。こちらは 500 エラーの問題とは関係がありませんでした。次に Mastodon の journalctl のログを確認してみると、AWS の認証情報が正しくない、というエラーを確認できました。ウェブで調べてみると、このエラーは一般的には鍵が違うとか、認証タイプが違う、というような場合に出るもののようです。Mastodon リリースノートでは Ceph を使う場合には S3_SIGNATURE_VERSION=s3 を指定するように、と書いてありましたので、.env.production にこちらを追記することで解決(リリースノートにはどこに書けって書いてませんけど!)。

とりあえず動いた

ここまで実施すると、とりあえず動くようになりました。しかし、まだ Access-Control-Allow-Origin 関係のエラーが出たままです。正直なところ、Content-Security-Policy の設定も自信がありません。なのであんまりいじわるしないでください。


やきたま
OTHER SNAPS