SMBを利用したGROWI構築

# はじめに
ラズパイを使ってmarkdownで書ける（ほぼ私用の）社内wikiを運用したいと思ったものの、SDカードがすぐに壊れる気分しかしなかったためコンテンツ部分を社内NAS上（プロトコルはSMBのみ）に置こう、と思ったところから話は始まる。
本稿は基本的にラズパイ4を前提しているため、前述のような理由だけならばUSBブートでSSDをブートドライブにする方が賢明やもしれない。とは言え、仕事のためにわざわざ身銭を切って信用できる外部ドライブを探すのも嫌だったためデータのみNASに移譲することとした。

本稿の流れは以下の通りである。
1. まず[必要となる環境・要件](#推奨環境（≒性能要件）)について説明し、
1. SMBを利用しない[GROWIを立ち上げ](#docker-composeを利用したGROWIのインストール
)
1. SMBの設定に必要となる[GROWIの情報を調べ](#mongoコンテナ内のユーザーmongoのUIDを確認)[^1]
1. 上記を加味して[SMBをマウント](#SMBのマウント)し
1. [GROWIのデータ保存先をSMBに変更してGROWIを再起動](#GROWIの保存先をSMBに変更)
[^1]:マウントするNASのプロトコルが例えばNFSなら恐らくGROWIの中身を考慮する必要はない

ただし、読み進めれば分かるが本稿でのSMBとGROWIの協調方法は暫定的なものであり、SMBやDockerに詳しい諸氏であればもっと適切な解決をできるだろう。

# 推奨環境（≒性能要件）
* ラズパイ4B（メモリ4GB以上）
* SD容量：16GB以上
* 64bitOS（必須）
  * ビルド時に2〜3GB程度メモリを食うようなので、足りない場合はスワップ領域を確保すること。3B+はメモリが1GBしかないが、スワップ領域を確保することでビルドできるらしい。

# docker-composeを利用したGROWIのインストール
## aptの更新
```
sudo apt update && sudo apt upgrade
```
## dockerのインストールと確認
```
curl -sSL https://get.docker.com | sh
docker --version
```
## docker-composeのインストールと確認
```
sudo apt-get install libffi-dev libssl-dev
sudo pip3 install docker-compose
docker-compose --version
```
## Raspberry Pi用にForkされたコンテナを取得
```
git clone https://github.com/temple1026/growi-docker-compose-pi.git growi
cd growi
```
## 環境変数の設定とdocker-compose.ymlの修正
```:growiディレクトリ
echo WORKDIR=$PWD > .env
sed s/\$PWD/\$WORKDIR/ docker-compose.yml > docker-compose.yml.tmp
sed s/127.0.0.1:// docker-compose.yml.tmp > docker-compose.yml
mkdir data
mkdir data/growi_data data/mongo_configdb data/mongo_db data/es_data
```
## ビルドして実行
```:growiディレクトリ
sudo docker-compose up -d --build
```
* このとき、メモリが不足しているとラズパイ全体の動作が固まる
    * 他のttyで動作をまともに受け付けないなどの症状がある場合、メモリ不足
    * htopなどを別のttyで事前に実行しておくと分かりやすい
* 適切に動作している場合、10～30分程度で立ち上がる

# mongoコンテナ内のユーザーmongoのUIDを確認
* ユーザー名mongodbだったかも？
```
sudo docker-compose exec mongo cat /etc/passwd | grep mongo
```
* 自分の環境では何度やってもUID/GIDともに999だったので、たぶん指定しなければ999？

# SMBのマウント
## 自動マウントするようにfstabに追記
```:/etc/fstab
//[server ip]/[path] /[mntpath] cifs [options],uid=999 0 0
```
* UIDをmongoのUIDに合わせる
    * ともかく、書きこむ予定のあるコンテナの書き込みを受け付けるようにしたいだけ
* その他のオプションについてはサーバーによって異なるため、適宜調べて行う

## /etc/fstabの確認兼マウント
```
mount -a
```
## 起動時のマウントをネットワーク確立後まで待機させる
```
sudo raspi-config 
```
```:raspi-config 
1.System Options > S6 Network at boot > YES > Finish
```

# GROWIの保存先をSMBに変更
## 環境変数の変更と、既存データの移行
```:growiディレクトリ
echo WORKDIR=/[mntpath]/growi > .env
mkdir /[mntpath]/growi
cp -r data /[mntpath]/growi/.
```
## dockerの停止と既存のボリュームを削除
```:growiディレクトリ
sudo docker-compose down
sudo docker volume rm growi_growi_data growi_mongo_configdb growi_mongo_db growi_es_data
```
## dockerの再ビルド・起動
```:growiディレクトリ
sudo docker-compose up -d --build
```

# 以上
* 本稿は社内Wikiが予定通り壊れた時用のメモ。

# 参考にしたサイト
* [ラズパイ上にDockerコンテナを使ってGrowiを簡単に構築する](https://qiita.com/reolch/items/15fc760de185716c029d)
    * ~~docker-compose.xmlの拡張子間違いと、docker-compose up -d --buildの-dが-bになってるのに苦しめられた~~
* [growi-docker-compose for Raspberry Pi](https://github.com/temple1026/growi-docker-compose-pi)
    * ~~これのREADMEが一番重要だった~~
* [ラズパイでNASをマウント](https://raspi-katsuyou.com/index.php/2020/12/27/19/00/42/2331/)
    * ~~username=guest,password=""ってやって爆死してた(正しくはpasswordに""を付けない)~~

# 所感(最後くらいは丁寧語で。ただし徒然)
自分は趣味でときどきプログラム書くくらいの素人なのでDockerなんていうのは名前を聞くくらいだったのですが、GROWIのスタンダードがdocker-composeのようだったので渋々さわる事と相成りました。
ちょっと上にも書いた通り、解説サイトの~~嘘~~誤表記に騙されて試行錯誤の末にインストールしたdockerを破壊(直接dockerバイナリをrmなど)し、元々別用に使っていた環境ではDockerが全く動作しなくなりました。
その過程で、Dockerを用いない方法で環境構築を3B+で行ったのですが、冒頭に書いたようにメモリの制約があり固まりまくりました。メモリの制約を正式に知ったのは、新しいSDカードを購入しラズパイ4BのSDを交換しGROWIがローカルで動作することを確認した後でした(htopで様子は見ていたのでたぶんメモリ不足だなとは思いましたが、スワップを増やす事に思い至りませんでした）。
今回、記事を書こうと思った最大の理由はこの誤表記記事が真っ先に見つかる事に対する反抗心ですね。

いざ当初の目的であるNASにデータを保存するという段になって、Dockerというものには困るなあと思いました。『どうやらmongodbでコンテンツを管理しているのだから、mongodbのDBデータをNAS上に置けば良い』と思ったものの、Dockerというのはmongodbがある環境自体をどこか謎の場所に置いてしまうのですね。/var/とかを探すのはたぶん筋違いだろうなと思いつつ、じゃあどうやって仮想環境からホスト側にデータ持ってくるんだ…。と1時間くらい考えてた気がします。

Dockerって凄いですね。はじめて触ったのに、動作するようになってから数時間でフォルダのバインドや環境変数の取り回しについて簡単な範囲で理解できるようになっていました。（その前日には破壊し尽くしたというのに）
この辺りから、Dockerって怖いなと思いました。gitやaptとかの管理ソフトと同じような怖さで、無理解なまま使えるので、どこかで大怪我する前にたくさん遊んでおきたいですね。

で、いざバインドしてみたらSMB上にデータを移動した時だけGROWIが起動せずでした。SMBに書きこめるUIDとDockerコンテナのUIDの不一致が原因であると推測する経緯は『fstabでUIDを指定していたからその辺に何かありそうだな』という程度でした。その推定自体は明文化された根拠を見つけたわけではなかったのですが確信があったので、なんとかしてDockerコンテナのUIDを指定する方法がないか調べました。
これ自体はわりとすぐに見つかって、docker-compose.ymlのmongoコンテナにuser: 999:999と指定しました。これで無事にGROWIも起動したのですが、docker-compose exec mongo bashを実行した際に、ユーザーID1000のユーザーが/etc/passwdにおらず、ログインユーザーがno nameとなってしまいました。動いているから良いのか、そうでもないのか…と悩み、結果的に今回記事に書いたようにfstab側の設定をmongoのUIDに寄せる形となりました。

**そういえば今回はmongoのUIDにだけ合わせていますが、growiやesのコンテナが何かを書きこむ時はそれらのUIDにも合わせないといけないので、その時は今のアプローチではダメですね。**

# 謝辞
GROWIやDockerのことが分からな過ぎてイライラして当たり散らした身近な人たちへの謝罪の言葉をここに述べさせていただきます。
またSNSでも不機嫌をまき散らした事を重ねてお詫び申し上げます。
すみませんでした。(謝辞の謝は感謝の謝では？)