今回CentOS7 Mastodon Docker利用構築
v1.2.2 -> v1.3.2のアップデートを
行った際にassetsのロードに失敗し、
Webページの画像やアイコン等が
表示されなくなりました。
アップデート時にぶつかった障害経験を共有いたします。
アプデはDBのバックアップ等を
きちんととってからやりましょう!
消えてしまうと悲しいことになります。
#簡単なアプデ経緯
他のQiita等で記載されているように、
gitでタグv1.3.2にチェックアウトして
rakeタスクにてprecompileと
DBのマイグレーションを掛けたら
本体(v1.3.2)の更新は完了でした。
この状態で表示や機能に問題はありませんでしたが、
公式のnginx設定例が変わっていたのでコピペしなおしたところ
ブラウザからのアクセス表示不正を起こしました。
#ポイントは/etc/nginx/conf.d/(お好きな名前).conf
問題は、gitに掲載されているnginxの設定例が
各バージョンのリリース地点で更新され、内容が異なっていることです。
そのため、「推奨設定を利用」と書かれたQiitaは多いですが、
実際にはタイミング次第で内容にばらつきが出ています。
Docker構築では本体をコンテナごと落としてくるので
設定の更新という観点がすっぽ抜けがちです。
ホストOS上に構築しているプロキシとしての
nginx設定も、本体の更新に応じて設定変更が
必要となる場合があることを覚えておきましょう。
#v1.2.2からの変更で修正が必要なもの
##DH鍵交換に必要なパラメータファイルの配置
新たな設定文が追加されたことにより、/etc/ssl/certs/dhparam.pem階層にTLS暗号通信で利用するファイルを配置する必要があります。
openssl dhparam 2048 -out dhparam.pem
で生成したファイルをその階層に配置しましょう。
##Let's Encrypt向け設定の無効化
いまひとつ使い方をよく理解できていないので、
Let's Encrypt向け設定も先頭に#をつけて
コメントアウトしておきました。
それほどシビアな運営をしていないので、
ダウンを伴うSSL鍵更新を自分は予定しています。
##assets消失を起こした設定文の修正(?)
自分の環境でassets消失を起こした原因はnginx設定のSSL通信部分にある
location ~ ^/(assets|system/media_attachments/files|system/accounts/avatars) {
add_header Cache-Control "public, max-age=31536000, immutable";
}
でした。
locationディレクティブはnginxが処理する
URIの階層に合わせた設定を記載するもので、
アセットやメディア、アバター周りのヘッダーに
何かをつけ足しているような処理ですが…
ここの正規表現に誤りがある?と思われ、
問題を引き起こしました。
自分のインスタンス環境(CentOS7 Docker)で回避策として機能したのは
上記部分をコメントアウトし、下記設定に置き換えでした。(参考)
location /assets {
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri @proxy;
}
明示的にアセットを含むURIを対象とした上で同じ値を設定し、
当該URIが発見できない場合try_filesディレクティブを利用して
@proxyの設定に飛ばしています。
同一問題を起こした方がいましたら、参考になれば幸いです。
#【おまけ】Let's Encrypt自動更新設定
安全な通信利用の促進のために、本来なら
有償であるサーバー証明書を発行してくれているのが
Let's Encryptです。取得・更新にかかる
管理コストを下げてくれるコマンドもありがたいですね。
ところが、この証明書の有効期限は
たったの90日(だったかな?)しかありません。
当然、更新を忘れると証明書が無効になってSSL接続時に
警告が表示されたり、アクセス不可能になります。
事前に対策しましょう。
##nginx停止を伴う更新
私のインスタンスにはユーザーも少ないですし、
サーバー停止にそれほどシビアな意見をもった人もいないと考えているので
一旦、certbotの更新処理は以下のようにnginx停止を含むものとしました。
おそらく、v1.3.2公開時の設定例に記載があるように、
nginxとうまく連携させれば無停止での更新が可能と思われますが…
そちらは興味があったら挑戦してみます。
certbot renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"
certbot renewコマンドは
証明書の期限切れが近い場合、
更新を行うコマンドです。
つまり、頻繁にこのコマンドを流しても
何度も何度も証明書が更新されるわけではありません。
ただし、--force-renewオプションをつけて実行すると
強制的に更新を行います。
cronで毎週回す、といった運用を行う場合は
負荷を高めることになりよろしくありません。
頻度と負荷を考えて設定しましょう。
--pre-hook,--post-hookオプションでは、
更新前後に行いたいコマンドを記載できます。
systemdを利用しているのでsystemctlから
nginxサービスを一旦停止し、更新処理を行います。
--dry-runオプションをつけた状態で実行すると、
テスト的に更新処理が成功するかどうか確認可能です。
cronに書き付ける前に、自分の環境で正しく動作するかを
チェックするとよいでしょう。
自分は毎月5日,20日の深夜にこのコマンドが走るようcronに設定しました。
実行にはroot権限が必要と思わしき表示が
--dry-run時に出ていたのでrootで回しています。
サーバー管理は実際に自分で動かしてみると一番勉強になりますし、
他人の知見や情報を読んだ際にも腹落ちするように思います。
楽しいますとどんライフの一助になれば幸いです。
それでは!