DockerでGrowiをセットアップする

# 概要
前から気になってるGrowiですが、docker-composeだと数行のコマンドでインストールが可能です。でも何となく使いたくないというか、詳しくない人間にとって、どこにデータが保存されているのかわからないものを使うのはやはり抵抗がありました。特にdockerはコンテナ削除すると中にあるデータも当然消えてしまうわけで、そんなものにいろいろ書き込むのは危険ですよね。
データを外に保存して、復元もできる方法をメモします。
mongodump等を使う方法もありますが、専用コンテナでそれほど規模も大きくない場合は丸ごとコピーで問題ないと思います。

# 環境

- Ubuntu 18.04
- ローカルで使用する (VirtualBox上で確認しました)

# 手順
ディレクトリは以下にしています。

- 作業ディレクトリ：`/home/ubuntu`
- データの保存先　：`/home/ubuntu/data`

公式手順通りダウンロードして、設定を変更します。

```
$ git clone https://github.com/weseek/growi-docker-compose.git
$ cd growi-docker-compose
$ vi docker-comopose.yml
```
変更箇所は以下。

- ローカルで使用するのでports:のIPアドレスは削除します。(127.0.0.1のままでもいいはず)
- environment:のPASSWORD_SEEDは任意の文字列に変更。この設定がないと自動で作成されるため、復元ができなくなる。取り出す方法もあるが、設定しておく方が簡単。毎回同じにする必要があるので、忘れないように。
- FILE_UPLOAD=localを有効化する。
- ホスト起動時に自動で起動するように設定する。具体的には、各コンテナに"restart: always"を設定する。(3か所)
- volumes:にホストのディレクトリを設定する。
  例えば、"growi_data:/data"となっているが、growi_dataは一番最後のvolumes:に定義だけあるが、実際のディレクトリが設定されていないので、このままではマウントされない。直で書いてもいいとは思いますがせっかく定義されているので。(オプションの意味は分かってないです^^;)

```docker-comopose.yml
services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 3000:3000    ### ローカルで使用するのでIPアドレスは削除 ###
    links:
      - mongo:mongo
      - elasticsearch:elasticsearch
    depends_on:
      - mongo
      - elasticsearch
    environment:
      - MONGO_URI=mongodb://mongo:27017/growi
      - ELASTICSEARCH_URI=http://elasticsearch:9200/growi
      - PASSWORD_SEED=changeme   ### changemeをランダムな文字列(MAX64桁)に変更する ###
      - FILE_UPLOAD=local        ### ローカルで使用するのでコメントを外す ###
      # - MATHJAX=1             
      # - PLANTUML_URI=http://  
      # - HACKMD_URI=http://    
      # - HACKMD_URI_FOR_SERVER=http://hackmd:3000 

    command: "dockerize
              -wait tcp://mongo:27017
              -wait tcp://elasticsearch:9200
              -timeout 60s
              npm run server:prod"
    volumes:
      - growi_data:/data
    restart: always      ### 自動起動の設定(追加) ###

  mongo:
    image: mongo:3.4
    volumes:
      - mongo_configdb:/data/configdb
      - mongo_db:/data/db
    restart: always      ### 自動起動の設定(追加) ###

  elasticsearch:
    image: elasticsearch:5.3-alpine
    environment:
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"  # increase amount if you have enough memory
    command:
      - sh
      - -c
      - "./bin/elasticsearch-plugin list | grep -q analysis-kuromoji || ./bin/elasticsearch-plugin install analysis-kuromoji;
        ./bin/elasticsearch-plugin list | grep -q analysis-icu || ./bin/elasticsearch-plugin install analysis-icu;
        /docker-entrypoint.sh elasticsearch"
    volumes:
      - es_data:/usr/share/elasticsearch/data
      - es_plugins:/usr/share/elasticsearch/plugins
      - ./esconfig:/usr/share/elasticsearch/config
    restart: always      ### 自動起動の設定(追加) ###

volumes:    ### 以下のようにホストのディレクトリを追記する ###
   growi_data:
      driver_opts:
        type: none
        device: /home/ubuntu/data/growi_data
        o: bind
   mongo_configdb:
      driver_opts:
        type: none
        device: /home/ubuntu/data/mongo_configdb
        o: bind
   mongo_db:
      driver_opts:
        type: none
        device: /home/ubuntu/data/mongo_db
        o: bind
   es_data:
      driver_opts:
        type: none
        device: /home/ubuntu/data/es_data
        o: bind
   es_plugins:
      driver_opts:
        type: none
        device: /home/ubuntu/data/es_plugins
        o: bind
```
ホストのディレクトリがないとエラーになるので起動前に作成しておく。

```
$ cd /home/ubuntu
$ mkdir data
$ cd data
$ mkdir growi_data mongo_configdb mongo_db es_data es_plugins
```
Docker起動する。

```
$ cd ~/growi-docker-compose
$ docker-compose up -d
```

起動すると、ホストの`/home/ubuntu/data`内にデータが保存されていく。
コンテナ消してもデータは消えないので安心。
バックアップは、このディレクトリごと保存しておけばいい。
復元も、保存したファイルを上書きするだけでいい。

もしうまくマウントできない場合は、UIDとかの関係だと思います。

## 備考
mongoDBのリストア機能使う場合…
詳細は他の情報サイトを探してください。(公式ドキュメントもある)

たぶん以下のようなやり方です。
※Growiが動作している状態で作業します。

```
# Dockerが使用しているネットワークを確認
$ docker network ls

# NAMEがgrowidockercompose_defaultというのがあるはず。("-"は省略される)
# 詳細を確認
$ docker network inspect growidockercompose_default

# "Name": "growidockercompose_mongo_1" みたいなのがあるはず。
# _defaultとmongo_1のネットワーク名を指定してコマンドを打つ

# バックアップ
$ docker run -it --rm --link growidockercompose_mongo_1 \
--network growidockercompose_default \
--volume $(pwd):/backup mongo bash -c "mongodump \
--host growidockercompose_mongo_1 --db growi --out /backup"

# アップロードしたファイルは、docker psでコンテナIDを確認し、
$ docker cp {your_growi_docker_container_id}:/data .


# リストア
$ docker run -it --rm --link growidockercompose_mongo_1 \
--network growidockercompose_default \
--volume $(pwd):/backup mongo bash -c "mongorestore \
-v --host growidockercompose_mongo_1 --db growi backup/growi"
$ docker cp ./data {your_growi_docker_container_id}:.
$ docker-compose restart
```



# 参考にしたサイト
- [Docker Composeのトップレベルvolumesでホストのディレクトリをマウントする](https://blog.moo-channel.net/2017/04/24/docker-composenototupureberuvolumesdehosutonodeirekutoriwomauntosuru-2/)
- [Crowiを導入して、運用していく。](https://www.changami.com/2017/11/feeling-for-crowi-introduced/)