Ubuntu 18.04にDockerでGROWIを構築する

# 概要

以前，CentOS上にGROWIをDockerで構築する手順を公開したがUbuntuでの構築方法もまとめてみた．


CentOSでの構築手順 ↓
[GROWIをDockerで構築する](https://qiita.com/tsumtsumyuma/items/7f0922cb00c6e14280b9)

# 環境

環境はESXi6.7上にUbuntu 18.04の仮想マシンをたてて，その上に構築する

| Software | Version |
|----|----|
| Ubuntu | 18.04 |
| Docker | 19.03.8 |
| Docker-Compose | 1.25.1 |

# パッケージのアップデート

```
sudo apt update
sudo apt upgrade
```

# dockerのインストール

## 1. Repositoryをアップデートする
- パッケージをインストールする

```
sudo apt install -y \
     apt-transport-https \
     ca-certificates \
     curl \
     software-properties-common
```

- DockerのGPG keyを追加する

```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

- Repository( stable ) を追加する

```
sudo add-apt-repository \
     "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
     $(lsb_release -cs) \
     stable"
```

- パッケージのupdateを実施する

```
sudo apt update
```

## 2. dockerをインストールする

- インストールする

```
sudo apt install -y docker-ce
```

- dockerの起動確認を行う

```
$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: e
   Active: active (running) since Sat 2020-03-21 12:25:35 JST; 28min ago
     Docs: https://docs.docker.com
 Main PID: 28276 (dockerd)
    Tasks: 31
   CGroup: /system.slice/docker.service
           tq 3549 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port
           tq 3603 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port
           mq28276 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/contai
```

## 3. 一般ユーザでもsudo無しでdockerを使えるようにする

- 一般ユーザをDocker groupに追加する

※<yourusername>の部分を変更する．この時「<,>」は必要ありません

```
sudo gpasswd -a <yourusername> docker
```

- dockerが使用するソケットを一般ユーザでも読み込み出来るようにする

```
sudo chmod 666 /var/run/docker.sock
```

# docker-composeのインストール

- 最新のバージョンを確認
    - [docker-composeのリリースノート](https://github.com/docker/compose/blob/master/CHANGELOG.md)
- 下記コマンドでダウンロード

```
export compose='1.25.1'
```

- /usr/local/bin/ 配下にダウンロード

```
sudo curl -L https://github.com/docker/compose/releases/download/${compose}/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
```

- 実行権限の付与

```
sudo chmod 0755 /usr/local/bin/docker-compose
```

- versionの確認

```
$ docker-compose -v
docker-compose version 1.25.1, build a82fef07
```

# gitをインストールする
- すでにインストール済みの場合もあるが一応．．．

```
sudo apt install git
```

# GROWIの構築
これで下準備は整ったのでGrowiをインストールしていきます．

## 1. GROWIをクローンする

今回は/opt以下に構築していきます．

```
# cd /opt
# sudo git clone https://github.com/weseek/growi-docker-compose.git growi
# cd growi
```
## 2. docker-compose .ymlを編集
続いてdocker-compose.ymlを編集していきます．

* サーバの外からもアクセスしたいので127.0.0.1は削除する
* 「FILE_UPLOAD=local」はコメントアウトを外すことでローカル(Docker内)に画像が保存できる
* 「elasticsearch:」の"ES_JAVA_OPTS=-Xms256m -Xmx256m"は"ES_JAVA_OPTS=-Xms512m -Xmx512m"にしておき，メモリに余裕がある場合は"ES_JAVA_OPTS=-Xms2g -Xmx2g"にしておいた方が良い．(メモリを少なく設定するとElasticsearchが起動しないことがある)

```
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
#      - 127.0.0.1:3000:3000    # localhost only by default
      - 3000:3000    # localhost only by default
    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
      # - FILE_UPLOAD=mongodb   # activate this line if you use MongoDB GridFS rather than AWS
      # - FILE_UPLOAD=local     # activate this line if you use local storage of server rather than AWS
      # - MATHJAX=1             # activate this line if you want to use MathJax
      # - PLANTUML_URI=http://  # activate this line and specify if you use your own PlantUML server rather than public plantuml.com
      # - HACKMD_URI=http://    # activate this line and specify HackMD server URI which can be accessed from GROWI client browsers
      # - HACKMD_URI_FOR_SERVER=http://hackmd:3000  # activate this line and specify HackMD server URI which can be accessed from this server container
      # - FORCE_WIKI_MODE='public'    # activate this line to force wiki public mode
      # - FORCE_WIKI_MODE='private'   # activate this line to force wiki private mode

    command: "dockerize
              -wait tcp://mongo:27017
              -wait tcp://elasticsearch:9200
              -timeout 60s
              npm run server:prod"
    restart: unless-stopped
    volumes:
      - growi_data:/data

  mongo:
    image: mongo:3.6
    restart: unless-stopped
    volumes:
      - mongo_configdb:/data/configdb
      - mongo_db:/data/db

  elasticsearch:
    build:
      context: ./elasticsearch
      dockerfile: ./Dockerfile
    environment:
      - bootstrap.memory_lock=true
#      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"  # increase amount if you have enough memory
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"  # increase amount if you have enough memory
    ulimits:
      memlock:
        soft: -1
        hard: -1
    restart: unless-stopped
    volumes:
      - es_data:/usr/share/elasticsearch/data
      - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

volumes:
  growi_data:
  mongo_configdb:
  mongo_db:
  es_data:

```

編集を終えたら保存しましょう

## 3. 起動
ここまで来たら後は起動するだけ

```
# docker-compose up
```

### 起動後

動作が安定するまでしばらくかかります．
http://{サーバのIP}:3000/
にアクセスすると初回画面が表示されますので，ユーザ情報を入力します．
ここで登録したユーザは自動的に管理者権限が付与されます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583643/c68e0990-6cec-3261-d1bf-084fe138887b.png)

### トラブルシューティング


# CodiMD連携(Option)
上記まででGROWIが使用可能となります．ここからはCodiMDと連携して複数同時編集を可能にします．機能の紹介はGROWIのドキュメントをご覧ください．

## 1. docker-compose.override.ymlファイルをdocker-compose.ymlと同じ階層にコピーする

- 作業前にGROWIが起動している場合は```docker-compose stop```でアプリケーションを停止させます．

GROWIをDockerでインストールするとGROWIフォルダ内に「examples」というフォルダがあり，examplesフォルダの中に「integrate-with-hackmd」フォルダがあり，その中に「docker-compose.override.yml」というファイルがあります．そのファイルをdocker-compose.ymlファイルと同じ階層にコピーします．

```
# sudo cp /opt/growi/examples/integrate-with-hackmd/docker-compose.override.yml /opt/growi/
```

## 2. docker-compose.override.ymlを編集する


- 「GROWI_URI」はブラウザでGROWIにアクセスするURLを入力します．例：http://{サーバのIP}:3000
- サーバ以外で使用したいので172.0.0.1は削除します．

```
version: '3'

services:
  ##
  # HackMD(CodiMD) container
  # see https://github.com/hackmdio/codimd#configuration
  #
  hackmd:
    build:
      context: ./hackmd
    environment:
      - GROWI_URI=http://192.168.0.101:3000
      - CMD_DB_URL=mysql://hackmd:hackmdpass@mariadb:3306/hackmd
      - CMD_CSP_ENABLE=false
    ports:
#      - 172.0.0.1:3100:3000   # localhost only by default
      - 3100:3000   # localhost only by default
    depends_on:
      - mariadb
    restart: unless-stopped

  ##
  # MariaDB
  # see https://hub.docker.com/_/mariadb/
  mariadb:
    image: mariadb:10.3
    command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci
    environment:
      - MYSQL_USER=hackmd
      - MYSQL_PASSWORD=hackmdpass
      - MYSQL_DATABASE=hackmd
      - MYSQL_RANDOM_ROOT_PASSWORD=true
    restart: unless-stopped
    volumes:
      - mariadb_data:/var/lib/mysql

volumes:
  mariadb_data:
```

編集を終えたら保存します．

## 3. docker-compose.ymlを編集する

- 「HACKMD_URI」と「HACKMD_URI_FOR_SERVER」のコメントアウトを外す
- 「HACKMD_URI」にはブラウザでCodiMDにアクセスするURLを入力します．例：http://{サーバのIP}:3100

```
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 3000:3000    # localhost only by default
    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
      # - FILE_UPLOAD=mongodb   # activate this line if you use MongoDB GridFS rather than AWS
      # - FILE_UPLOAD=local     # activate this line if you use local storage of server rather than AWS
      # - MATHJAX=1             # activate this line if you want to use MathJax
      # - PLANTUML_URI=http://  # activate this line and specify if you use your own PlantUML server rather than public plantuml.com
      - HACKMD_URI=http://192.168.0.101:3100    # activate this line and specify HackMD server URI which can be accessed from GROWI client browsers
      # - HACKMD_URI_FOR_SERVER=http://hackmd:3000  # activate this line and specify HackMD server URI which can be accessed from this server container
      # - FORCE_WIKI_MODE='public'    # activate this line to force wiki public mode
      # - FORCE_WIKI_MODE='private'   # activate this line to force wiki private mode

    command: "dockerize
              -wait tcp://mongo:27017
              -wait tcp://elasticsearch:9200
              -timeout 60s
              npm run server:prod"
    restart: unless-stopped
    volumes:
      - growi_data:/data

  mongo:
    image: mongo:3.6
    restart: unless-stopped
    volumes:
      - mongo_configdb:/data/configdb
      - mongo_db:/data/db

  elasticsearch:
    build:
      context: ./elasticsearch
      dockerfile: ./Dockerfile
    environment:
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"  # increase amount if you have enough memory
    ulimits:
      memlock:
        soft: -1
        hard: -1
    restart: unless-stopped
    volumes:
      - es_data:/usr/share/elasticsearch/data
      - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

volumes:
  growi_data:
  mongo_configdb:
  mongo_db:
  es_data:

```

編集を終えたら保存します．

## 4. 起動
ここまで来たらGROWIと同様に起動します．

```
# docker-compose up
```

自動的にCodiMDがインストールされ起動します．

- CodiMDには1GBほどのメモリを消費するため，elasticsearchに割り当てたメモリによっては起動しないことがあるため注意

## 5. サイトURLの設定

ブラウザからGROWIにアクセスし，「管理 > アプリ設定 > サイトURL設定」に進む．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583643/ddb1523d-509c-f682-d3b1-cf2e7b04a0c1.png)

「Database」の項目に先ほどdocker-compose.override.ymlのGROWI_URIで設定したアドレスを入力し「更新」をクリックする．

## 6. 使用方法
- 「HackMD」をクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583643/b4d8fb0f-5013-71cc-8fb4-de3bbd2b0868.png)

- Start to edit with HackMDをクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583643/486a78b4-1b26-322f-b9cf-57de39426e96.png)

- 下記のような画面が表示されればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583643/8226f867-358d-f0b7-ff31-a7cef948ab20.png)

### 注意

新規ページの場合は先にGROWIのエディタで何か入力し一旦ページを作成しないとHackMDモードでの編集ができない．

# Sidebar(Option)

**現状v4.0.0以降では動作しません**

- GROWIに正式に実装されているわけではないが以下のページを参考にさせていただき，Sidebarを実装しました．
- 管理 > カスタマイズ > カスタムスクリプトに以下のコードを記載することでSidebarが使用できます．

```
// sidebarのリンク
var links = [
  ["/sample1", "sample 1"],
  ["/sample2", "sample 2"],
  
  ["/admin/customize", "(customize this)"],
]
/*
 sidebarにリンク作る
 */
var sidemenu = document.querySelector('#side-menu');
if (sidemenu) {
  var li = function(href, name){
    return '<li class="tbd"><a href="' + href + '">' + name + '</a></li>'
  }
  innerHTML = ""
  for (var i=0; i<links.length; i++){
    innerHTML += li(links[i][0], links[i][1])
  }
  sidemenu.innerHTML = innerHTML;
}
```

# まとめ

UbuntuでもGROWIを構築することができた．

# 参考

##### dockerのインストール関連
[Ubuntu 18.04にDockerをインストールする(+docker-composeも)](https://qiita.com/iganari/items/fe4889943f22fd63692a)

##### gitインストール
[UbuntuにGitをインストールする](https://qiita.com/tommy_g/items/771ac45b89b02e8a5d64)

##### growiインストール
[GROWI Docs](https://docs.growi.org/ja/admin-guide/getting-started/docker-compose.html)
[GROWIをDockerで構築する(CodiMD連携)](https://qiita.com/tsumtsumyuma/items/7f0922cb00c6e14280b9)