Raspberry Pi 4 Model B (Ubuntu) に GROWI 導入

# はじめに
本記事は、以前 Raspberry Pi 4 Model B（以降 RP4B）上に、プライベートな Wiki として [GROWI](https://growi.org/ja/) を構築したときの作業手順をまとめたものである。
公式の Docker イメージを使った導入がうまく行かなかったので、手作業でやってみた。

なお、 RP4B 自体の初期セットアップについては事前に完了しているものとして、本記事では扱わない。

## 環境
- Raspberry Pi 4 Model B 4GB (32GB MicroSD)
- Ubuntu Server 19.10.1 (64bit)
- GROWI 3.7.5

本記事内では、各種ネットワークアドレスについて以下のように仮定する。

- ローカルネットワークの IP アドレス範囲は 192.168.1.0/24 とする。
- 対象となる RP4B の IP アドレスは 192.168.1.10 とする。

## 参考ページ
- [GROWI 公式ドキュメント](https://docs.growi.org/ja/admin-guide/getting-started/ubuntu-server.html)
- [RP3 Elasticsearch 導入事例](https://tech.taiko19xx.net/entry/2018/01/14/210400)
- [Elasticsearch 公式ドキュメント](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/zip-targz.html)

# nodejs
- nodejs 12.16.3
- npm 6.14.4
- yarn 1.22.4

（このあたり記憶があやふやだが）基本的には[公式ドキュメント](https://docs.growi.org/ja/admin-guide/getting-started/ubuntu-server.html)の手順に沿ってやれば良かったはず。
ただし GROWI 3.6 以降からは nodejs のバージョンが 10.x か 12.x である必要があるので、そこだけ読み替える。

```bash
$ cd ~
$ curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh
$ sudo bash nodesource_setup.sh
$ sudo apt install nodejs
$ sudo npm install -g yarn # グローバルインストール
```

nodejs のセットアップが成功すると以下のファイルが作成され、リポジトリが追加される。

```:/etc/apt/sources.list.d/nodesource.list
deb https://deb.nodesource.com/node_12.x eoan main
deb-src https://deb.nodesource.com/node_12.x eoan main
```

# Elasticsearch
- elasticsearch 6.8.8
- openjdk 8 (1.8.0_252)

[ここ](https://tech.taiko19xx.net/entry/2018/01/14/210400)を参考にやった。

まずは Java を導入。

```bash
$ sudo apt install openjdk-8-jre
```

複数のバージョンの Java を導入している場合は以下コマンドで切り替える（不要かも）
（参考サイト： http://note.kurodigi.com/post-0-2/ ）

```bash
$ sudo update-alternatives -config java
# インストール済みバージョンが列挙される。
# 使用したいバージョンの番号を入力して Enter を押す。
```

Elasticsearch のアーカイブファイルを DL してきて展開する。
導入するバージョンは[公式サイト](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/zip-targz.html)を確認して 6.x 系の最新版にするのが良さげ。

Elasticsearch は [root ユーザでは起動できないという罠](https://confluence.atlassian.com/bitbucketserverkb/when-using-the-root-user-elasticsearch-cannot-be-started-due-to-don-t-run-elasticsearch-as-root-847751401.html)がある。
なので、適当な root 以外のユーザのホームディレクトリ以下に展開するのが良さそう。
今回は /home/{username}/.local/elasticsearch-6.8.8/ として展開した。

```bash
$ cd ~
$ mkdir .local
$ chmod 755 .local
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.8.tar.gz
$ tar zxvf elasticsearch-6.8.8.tar.gz -C .local
$ cd .local
$ ln -s elasticsearch-6.8.8 elasticsearch # シンボリックリンク作成
$ echo "xpack.ml.enabled: false" >> elasticsearch/config/elasticsearch.yml # X-Pack Machine Learning が ARM 環境下では動作しないので無効にする。
```

動作テストする。

```bash
$ cd ~
$ cd .local/elasticsearch
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64
$ ./bin/elasticsearch & # バックグラウンドプロセスとして起動
$ curl http://localhost:9200
```

## サービス化
[ここ](https://qiita.com/Y-Shikase/items/7e6025855454c443f620)を参考にサービスとして登録する。
まずは su 権限で elasticsearch.service ファイルを作成する。

```:/etc/systemd/system/elasticsearch.service
[Unit]
After=syslog.target network.target

[Service]
Environment="JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64"
ExecStart=/home/{username}/.local/elasticsearch/bin/elasticsearch
WorkingDirectory=/home/{username}/.local/elasticsearch
User={username}
Group={groupname}
Nice=10
SyslogIdentifier=Elasticsearch
StandardOutput=syslog
Restart=on-failure
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target
```

起動可能か確認した後、自動起動設定する。

```bash
$ sudo systemctl start elasticsearch  # 手動起動
$ sudo systemctl status elasticsearch # 正常に動作しているか確認
$ sudo systemctl enable elasticsearch # 自動起動設定
```

## プラグイン導入
- analysis-kuromoji
- analysis-icu

```bash
$ cd ~
$ cd .local/elasticsearch
$ bin/elasticsearch-plugin install analysis-kuromoji
$ bin/elasticsearch-plugin install analysis-icu
$ ls -la plugin # DL したプラグインを確認
$ sudo systemctl restart elasticsearch # 再起動
```

# MongoDB
- mongodb 3.6.8

```bash
$ sudo apt install mongodb-server
$ sudo systemctl start mongodb
$ sudo systemctl status mongodb
$ sudo systemctl enable mongodb
```

# GROWI
- growi 3.7.5

[公式ドキュメント](https://docs.growi.org/ja/admin-guide/getting-started/ubuntu-server.html)の手順に沿ってやる。
ビルドにそこそこ時間がかかるので注意。

```bash
$ cd /opt
$ sudo git clone https://github.com/weseek/growi /opt/growi
$ cd /opt/growi
$ sudo git tag -l # RC が付いていない最新版を確認
$ sudo git checkout -b v3.7.5 refs/tags/v3.7.5 # tag からブランチを切ってチェックアウト
$ sudo yarn # 12分程度かかった
```

動作テストする。
起動後は ctrl+z でバックグラウンドプロセス化して確認。

```bash
$ sudo ufw allow from 192.168.1.0/24 to any port 3000 # ローカルネットワークにおいて 3000番ポートを開放
$ sudo \
  MONGO_URI=mongodb://localhost:27017/growi \
  ELASTICSEARCH_URI=http://localhost:9200/growi \
  npm start
# 以下メッセージが表示されるまで待つ（そこそこ時間がかかる）
> growi@3.7.5 server:prod /opt/growi
> env-cmd -f config/env.prod.js node src/server/app.js
```

http://192.168.1.10:3000/ にアクセスしてみて、初回セットアップ画面が表示されるか確認。

## サービス化
[公式ドキュメント](https://docs.growi.org/ja/admin-guide/admin-cookbook/launch-with-systemd.html)を参考に適当に読み替えてやる。
まずは su 権限で growi.service ファイルを作成する。
ファイルアップロードは MongoDB GridFS にしておく。

```:/etc/systemd/system/growi.service
[Unit]
Description=Growi
After=network.target mongodb.service elasticsearch.service

[Service]
WorkingDirectory=/opt/growi
Environment=PORT=3000 \
            MONGO_URI=mongodb://localhost:27017/growi \
            ELASTICSEARCH_URI=http://localhost:9200/growi \
            FILE_UPLOAD=mongodb \
            MATHJAX=1
ExecStart=/usr/bin/npm start

[Install]
WantedBy=multi-user.target
```

起動可能か確認した後、自動起動設定する。

```bash
$ sudo systemctl start growi
$ sudo systemctl status growi
$ sudo systemctl enable growi
```

## プラグイン導入
- growi-plugin-lsx
- growi-plugin-pukiwiki-like-linker

[公式ドキュメント](https://docs.growi.org/ja/admin-guide/management-cookbook/app-settings.html#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E8%A8%AD%E5%AE%9A)とプラグインの GitHub を確認しつつ進める。
結構時間かかる。

```bash
$ sudo npm install --save growi-plugin-lsx
$ sudo npm install --save growi-plugin-pukiwiki-like-linker
$ cd /opt/growi
$ sudo systemctl stop growi
$ sudo yarn
$ sudo systemctl start growi
```