crowiをアップデートする（1.6.2 -> 1.7.0）

## 背景

所属しているグループで、内部WikiとしてCrowiサーバーを立てて使っています。

http://site.crowi.wiki/

これまでv1.6.2を使っていましたが、この前[GitHubのレポジトリ](https://github.com/crowi/crowi)を見に行ったら[1.7.0](https://github.com/crowi/crowi/releases/tag/v1.7.0)がリリースされていました。

1.6.2ではMathJaxが少しおかしかったりしたので（これは既に1.6.3で直されていたようですが）、いい機会ということでアップグレードすることにしました。これはそのログです。

したことは、

1. バックアップ
2. Node.jsのアップデート
3. Elasticsearchのアップデート
4. Crowiのアップデート

です。Redis, MongoDBは変更していません。外部サービスとの連携は最初から入れていません。

環境は、Ubuntu 16.04、x86_64です。この辺りの知識は幾多のサーバーを吹き飛ばしながら独学しており、本すら読んでいないので、間違ったことが含まれているかもしれません。内部用なので色々と雑ですが一例として参考になれば。

## バックアップ

何はともあれまずはバックアップを取ります。これで、誤ってサーバーを爆発四散させてしまっても一から立て直すことで事なきを得られます。これは、以前別のマシンに移し替えた時と同じ手段を使っています。

CrowiのコンテンツはMongoDBによって管理されています。このバックアップを取る一番簡単な手順は、単にファイルを全てコピーしてしまうことでしょう。何も頭を使わずに済みます。ファイル容量がすさまじい場合は、`mongodump`を使うと（実行時間が長くなる代わりに）ファイルが小さくなるそうです。今回はそこまで大容量でないので気にしません。

以下の手順は、この記事を参考にしました。http://gihyo.jp/dev/serial/01/mongodb/0011

何はともあれ、書き込みを防ぐためにmongo shellからロックを取得します。サービスを単に止めてしまってもいいのではと思います。

```console
> use admin
> db.fsyncLock()
```

その後、単にファイルをコピーします。

```console
$ cp -rp /var/lib/mongodb ./crowi-mongodb-bak-180921
$ tar zcvf crowi-mongodb-bak-180921.tar.gz ./crowi-mongodb-bak-180921
$ scp crowi-mongodb-bak-180921.tar.gz somewhere:.
```

簡単。

それと、Crowiのローカルにアップロードされているファイルは、`/path/to/crowi/public/uploads/`の中に入っているので、これもバックアップしておきます。単にファイルをコピーして置いておくだけで大丈夫でした。少なくとも1.6の頃は。

最終的にサーバーが爆発しなかったので、このバックアップファイルは未だ使われることなく眠っています。

## node.js 6.x -> 8.x

crowi 1.7.0ではnodejsのバージョンが上がっています。

今はCrowiサーバはCrowiのためだけに立てているので、nodejsのバージョンを変えられるようにする必要を感じておらず、nvmなどは使わず単にaptで導入しています。なので、以下の記事を参考に、aptからアップグレードします。

https://nodesource.com/blog/installing-node-js-8-tutorial-linux-via-package-manager/

```console
$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
$ sudo apt-get install -y nodejs
$ node -v
v8.12.0
```

これは特に問題もなく済みました。

## Elasticsarch 5.x -> 6.x

次はElasticsearchのバージョンを上げます。公式サイトからdebファイルを取ってきます。

https://www.elastic.co/jp/products/elasticsearch

なんとなく気になるのでElasticsearchを止めて(Crowiを止めてあるので問題なし)、debファイルをdpkgに渡し、アップグレードします。

```console
# systemctl stop elasticsearch.service
# dpkg -i elasticsearch-6.4.1.deb
# apt-get update
# apt-get upgrade
```

その後、日本語形態素解析パッケージ「kuromoji」をアップデートしなければなりません。これを忘れるとバージョン違いでElasticsearchが異常終了します（1敗）。

アップデートするには、単に`install`すると「既にある」と言われたので、一度消してインストールしなおす必要があるようです。

```console
# /usr/share/elasticsearch/bin/elasticsearch-plugin remove  analysis-kuromoji
# /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
```

起動したら、Elasticsearchのポートを見るとバージョン番号の書かれたJSONが来るので、アップデートされたかどうか確認できます。

```console
# systemctl start elasticsearch.service
# systemctl status elasticsearch.service
# curl localhost:9200
{
  ...
  "version" : {
    "number" : "6.4.1",
    ...
  },
  ...
}
```

Elasticsearch自前のプラグインマネージャの存在をよく忘れるのだけが落とし穴です。

## crowi 1.6.2 -> 1.7.0

本丸を攻略します。

crowiのレポジトリを`git clone`してきているので、まずは`v1.7.0`のタグへ飛びましょう。ちなみに、masterブランチは不安定なので使用は推奨されていません。

当時以下と同様の手順で切った1.6.2ブランチにいたので、masterに戻って一度pullしていましたが、`fetch`だけで平気なのではという疑惑が浮上しています。

```console
$ git checkout master
$ git pull origin master
$ git fetch origin
$ git checkout -b 1.7.0 v1.7.0
```

その後`npm install`を実行します。忘れるとCrowiが起動に失敗します（1敗）。また、このとき`--unsafe-perm`がついていないとエラーが出ます（1敗）。

```console
# npm install -g --unsafe-perm
```

さて、実行時の設定やコマンドは変わらないので、そのままリスタートすれば立ち上がります。

最後に、Elasticsearchのバージョンアップのせいで検索用インデックスを再構築する必要があります。Crowiの管理者はCrowiの管理ページにアクセスすることで実行できます。

というわけで、Index Buildボタンを押して終了です。お疲れ様でした。

（再起動後の数分間、Crowiのページ遷移が非常に重くて少し冷や汗をかきましたが、しばらくすると軽快に動くようになりました）