Mastodon Non-Docker Ubuntu16.04 LTS から18.04 LTS へのアップデートで死にかけた話

# そろそろ期限切れよね 16.04 LTS
と思ってアップデートしたんだけど、実はまだ2年余裕がありました。とはいえアップデートはいいことなので行います
アップデート手順はあちこちにあるので省略しますが、アップデート再起動の後のやらなきゃいけないことをちょこちょこ書いていきます
## Postgresql 10 へ移行
16.04 は 9.5でしたが 18.04 は 10 です。データをちゃんと移行しないといけません

```sh
$ sudo systemctl stop mastodon-web.service
$ sudo systemctl stop mastodon-sidekiq.service
$ sudo systemctl stop mastodon-streaming.service
$ sudo pg_dropcluster 10 main --stop
$ sudo service postgresql stop
$ sudo pg_upgradecluster 9.5 main
```
Mastodon のサービスを止め 10 のデータベース関係を止めてから Postgresql を止めて、9.5 のデータを 10. にアップグレード。これは少し時間がかかります

```sh
$ sudo service postgresql restart
$ psql --version
```
終わったらデータベースを起動。バージョンを確認。

```sh
$ sudo pg_dropcluster 9.5 main
```
これでデータベース移行完了。なんかエラー出てた気がするけど pg_lsclursters で見て 9.5 が消えてれば終了（割と適当）

```sh
$ sudo systemctl start mastodon-web.service
$ sudo systemctl start mastodon-sidekiq.service
$ sudo systemctl start mastodon-streaming.service
```
Mastodon サービスをリスタートしてみたんですがなんかエラー。ここからがしばらくハマりました。最悪サービス止めようかと思うくらいには

## bundler と precompile のやりなおし
困ったときは precompile。結果間違いだったんですけど問題点の洗い出しには役立ちました

```sh
$ RAILS_ENV=production bundle exec rails assets:precompile
```
libicuuc.so.55 がないというエラー。検索して引っかかった[StackOverflow のページ](https://stackoverflow.com/questions/35840359/libicuuc-so-55-cannot-open-shared-object-file)を見てインストール
今度はlibprotobuf.so.9……いやこの解決方法はおかしいぞ、と暫く考えます
しばらくウロウロ検索しているとMastodonのvendorディレクトリ下にコンパイルされたバイナリが入るという情報をどこかで拾ったので以下の処理を実行

```sh
$ mv vendor vendor.old
$ bundle install --deployment --without development test
$ yarn install
$ RAILS_ENV=production bundle exec rails assets:precompile
```

終了後 Mastodon サービスリスタート。ブラウザでアクセスするとトップ画面が表示されました。めでたしめでたし……ではありませんでした。その後ログインするとコケてしまいます

## Redis の設定をいじる

しばらく悩んでいましたがどこが悪いのかさっぱり。ログをウロウロしていると、Redisがなんか怪しいログを吐いていることに気が付きました

```redis-server.log
XXXXX:C DD MMM HH:MI:SS.SSS # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
XXXXX:C DD MMM HH:MI:SS.SSS # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=16809, just started
XXXXX:C DD MMM HH:MI:SS.SSS # Configuration loaded
XXXXX:M DD MMM HH:MI:SS.SSS # Creating Server TCP listening socket ::1:6379: bind: Cannot assign requested address
```

ソケットのバインドに失敗……？
設定ファイルを眺めます。特におかしなことはなさそうな気がするんだけど……？

```redis.conf
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1 ::1
```

ローカルにバインドの設定よね。不審な点……あれ……？

```redis-server.log
XXXXX:M DD MMM HH:MI:SS.SSS # Creating Server TCP listening socket ::1:6379: bind: Cannot assign requested address
```
もしかして ::1 が原因ですか……設定の ::1 を削除して redis を起動すると無事起動成功。これでアップデート完了

ここまで2時間ほど格闘しました。もう少し頑張りましょう自分