📚

組織のナレッジベースにOSSのGrowiをAWSホスティングする話

2024/10/20に公開

概要

みなさま今日も元気にナレッジを貯めていますか。

世の中は広くみんなに知ってもらいたい知識や、社内や身内に閉じる知識があります。
後者は例えばお仕事で作ってるプロジェクト固有の議事録とかですね。

こういうのを残しておくためのナレッジベースはさまざまな製品があります。
今回はOSSで提供されてるGrowiをお試しでAWSに建てて調べたことを書きます(SaaSとして Growiを使うGrowi.cloud https://growi.cloud/ もあります。お金で解決できるって素敵!)

Growiってなに

OSSのナレッジベースです。歴史のあるOSSで https://growi.org/ja/ 100万回Docker pullされた(つまり数十万回は起動してる)ソフトウェアです。

僕の知る限りでは日本に開発主体があるOSSのナレッジベースとして一番機能が多い気がします。

公式サイトよりスクショ。draw.io連携やPlantUML対応、同時編集などもあって便利そう!

他の選択肢は何があるの

Confluenceやesa,Qiita:teamなどはユーザ1人あたり課金のビジネスモデルです。
お金で解決できるって素敵(2回目)
ただ、想定100人が使う!とかだと人数ベース課金のサービスが意外に苦しくなることもあります。

GrowiはOSSでセルフホスト可能なので、AWSに構築しちゃえば相対的に安く維持ができそうですね。

注意:利用人数ではなく利用規模に応じたコストになる、というのが今回の選定ポイントで、利用規模がめちゃくちゃ大きくなるくらい組織の活動が活発なら、インフラコストがその分かかります。

他のOSSのwikiエンジンを使うと言うのも手ですが、今回調べた限りでは一番僕のおすすめがGrowiです。

GrowiをAWS上に構築してみよう

今回はお試しという意図でAWS上に構築します。
もしケチケチコースなら適当なVPSを借りたり、手元のPCを使ったり出来ると思います。
(例えばVPSなら、Contaboなど価格の割にスペックの高いものが使えます)

AWSのEC2で作るメリットの一つは、セキュリティグループの設定によって外部の通信をインスタンスより手前のレイヤーで保護できるため、環境構築中などに安心して作業が出来ることだと思っています。

どちらかというとGrowiはLAN内など閉じたネットワーク環境の運用例が多い気もしますが、今回はAWSを使います。(なぜなら僕はリモート勤務なので…そっちの方が嬉しいからです)

ec2でGrowiを動かす準備

GrowiはDocker Composeでのセットアップが推奨されています。
https://docs.growi.org/ja/admin-guide/getting-started/docker-compose.html
基本的には本家のドキュメントに従って作業になります。

EC2インスタンスは

  • Ubuntu24.04で良い(x64アーキテクチャを選びましょう)
  • t2.small程度からスタートで良い
  • ERBが20GB程度は必要(8GBだと環境構築に失敗します。画像データなどをローカルのmongoに保存する関係である程度大きなディスクを割り当てた方が良いです)

の単一インスタンスを使います。特にこだわりが無ければ東京リージョンにしてください。

EC2へのSSH接続など

  • セットアップが終わるまでインバウンドのSSHはマイIPに限定しておく
  • 他のポートもインバウンドは不許可にしてあることを確認する
  • key-pairで接続する
    など、セキュリティに気をつけてください。

必要なソフトのインストール

EC2インスタンスにSSHでログインできた後、growiのサーバを起動可能にするため各種ソフトをインストールします。

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

sudo apt update
sudo apt upgrade -y

DockerおよびDocker Composeのインストール

ここを参照してください。念のため書いておきます

https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script

Dockerのインストールスクリプト

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

Dockerインストール済みなことをバージョン出力で確認

docker -v

Docker Composeもインストールします。

sudo apt install docker-compose

Docker Composeのインストールが無事完了していることをバージョン出力で確認

docker-compose -v

リポジトリのチェックアウトをします。
growiではなく、growiを立ち上げるDocker Composeの設定群をチェックアウトしていることに注意してください。

git clone https://github.com/weseek/growi-docker-compose.git growi

該当のリポジトリに移動

cd growi

ここまでで立ち上げる準備が出来ました。
growi の中でlsをしてみて、docker-compose.ymlなどのファイルがあることを確認しましょう。

EC2インスタンスでGrowiを動かしてみよう

docker-compose.ymlの編集

最小限の変更をします。

  • portsをlocalhost限定から外部アクセス可能に変更(127.0.0.1:3000:3000を3000:3000に書き換え)
  • FILE_UPLOADをmongodbに変更
  • MathJSを有効化(これはお好みで)
  • AUDIT_LOG_ENABLED = true (監査ログ用)

Attachment Files(つまり、記事に追加する画像ファイルなどです)をローカルやS3にせず、全て元からあるmongodbに保存することで、後述のお引越しなどで楽ができます。

DockerFileの編集

ARG version=7

ARG version=7.0.21

などバージョンを決め打ちしておきます(バージョン差異にハマらないようにするためです)

現時点だとこのようなバージョンになります。
(これはGrowiの管理画面のシステム情報です)

Growiの起動

sudo docker compose up

で初回起動が行われます。おおよそ10-15分程度時間がかかるのでコーヒー ☕️を飲んでおきましょう。

その後、セキュリティグループでインバウンドの 3000番ポートをマイIPだけ開けます

(Growi初回起動は管理者アカウント作成のため、初回起動直後が一番脆弱です)

無事コーヒーを飲んで一息ついたら
http://xx.yyy.zzz.aaa:3000/
にアクセスしてください。(EC2の外部IPを指定してください)
最初に登録したユーザがadminになるためこの時点まで外部からのアクセスを避けて環境構築をしましょう

管理者アカウントとして最初に行うこと

この時点で友達に「見てみて!!Growiできた!アクセスしてみて!!」と見せることができます。

ただ、Growiの初期設定のままだと外部公開する時に少し怖いところもあるので、人に見せるにはいくつか設定を確認してからにしましょう。
Growiの管理者アカウントで admin/securityを覗いて、以下の設定をしましょう。

  • ページの閲覧権限

    • ゲストユーザーのアクセス→拒否
  • 認証機構

    • ID/Passwordを有効にする
    • 登録の制限:制限(登録完了には管理者の承認が必要)

ここまでの作業を終えてからEC2インスタンスのセキュリティグループのインバウンドで3000ポートをAnyIP にします。
他の人から(あなたのスマホ回線からも!)Growiにアクセスできるようになります。
記事の書き方などを練習してみましょう。

ドメイン紐付けとSSL証明書対応を使用

ec2のIPアドレス直打ちでアクセスは出来ますが、このままではIP直打ちだしhttps通信に対応していないし変な3000番ポートでアクセスする ことになっています。

これは不便なので、ドメインを取得したり各種設定をして、普通のWebサイトのようにアクセスできるようにしましょう。

  • Route53でドメイン取得 (AWSのお作法なので省略)
  • Elastic IPでIPの固定化 (AWSのお作法なので省略)
  • nginxを入れてリバースプロキシ設定(通信をport80/443で受けてport3000のGrowiに中継する)
  • SSL証明書の設定

Growiオフィシャルのnginxを入れてリバースプロキシ設定+SSL証明書設定はこの手順です。
https://docs.growi.org/ja/admin-guide/admin-cookbook/lets-encrypt.html
(内部でhttps-portalを使ってSSLの有効化+nginxのリバースプロキシ設定をしています。
https://github.com/SteveLTN/https-portal/blob/master/README-ja.md )

docker-composeでの構築をしておくと、ほんの数行の追加でhttps-portal経由でnginx+Let's EncryptでのSSLが(証明書の自動更新込みで)完了します。すごい!便利!

Growiを使わなかった方もnginx+Let'sEncryptを簡単に設定できるhttps-portalだけは覚えておきましょうね。

この作業をする時、セキュリティグループでHTTPS,HTTPをインバウンドでAnyIPで許可する必要があります(証明書の通信のため)

また、リバースプロキシに Nginx を利用している場合は、その制限を受けます。1Mバイトを超えるファイルをアップロードする必要がある場合は、client_max_body_sizeディレクティブを設定してください。

例えばこう設定します。

environment:
CLIENT_MAX_BODY_SIZE: 0  # これだと無制限。これでいいかも

念の為、今回のdocker-compose.override.yml設定例を書いておきます

version: '3'

services:
  # a fully automated HTTPS server powered by Nginx, Let's Encrypt
  # see https://github.com/SteveLTN/https-portal
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - '80:80'
      - '443:443'
    links:
      - app:app
    environment:
      # ドメイン指定。あなたの取得したドメインを書いてください
      DOMAINS: 'growi.example.com -> http://app:3000'
      # この行を消すとオレオレ証明書になります
      # productionなら証明書の通信で80,443がAnyIPで通信可能にしておくこと!
      STAGE: 'production'
      FORCE_RENEW: 'false'
      # Growi7.x系からWebsocket通信が必須です
      WEBSOCKET: 'true'
      # nginxデフォルトは1MBまでしかファイルがアップできないので無制限にする
      # http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size 参照
      CLIENT_MAX_BODY_SIZE: 0
    restart: unless-stopped
    volumes:
      - https-portal_data:/var/lib/https-portal

volumes:
  https-portal_data:

使ってみよう

ここはどちらかと言うとそれぞれの使い方があると思うので一旦白紙にしておきます。

補遺:お仕事で検討する人向けの情報

公式サイトにも書いてあったりしますが、ちゃんと調べておくと安心して使えますよね。
大体お仕事で必要そうなことをまとめておきました。
共有ファイルサーバで良いじゃん。Growiは怖いじゃん!!って言う上司の人を説得する時にでも使ってください。

データバックアップおよびお引越しの検証

ここに詳しい手順があります。

社内でGrowiを立ち上げてみた(補足その3)
https://qiita.com/cohpen/items/65cf6f2dcabbd9e6a307

Growi公式には移行ツールがあったりしますが、正直なところ DBを直接バックアップしてリストアする方が安心 です。

上の環境設定でAttachmentをMongoDBに保存、としておいたのはこのお引越しをMongoDBのdumpとrestoreで完結させるためです。
growi_mongo_1はデフォルトの設定なので、変更していたら適宜読み替えてください。

データのバックアップ

e2上のhostでdocker上のmongodbのdump

sudo docker exec -d growi_mongo_1 mongodump --archive=mongodb.archive

dockerからhostOS(EC2上のUbuntu)にarchiveをコピー

sudo docker cp growi_mongo_1:/mongodb.archive ./

これをやってmongodb.archiveを取得する

手元のMacにダウンロードするときは

scp -i "your-key.pem" ubuntu@xx.xxxx.xxxxx.xxx:~/mongodb.archive ~/Downloads

などをします。

引越し先にデータのコピー

引越し先のEC2上で同じくgrowiが起動できていることを確認してから作業します。
絶対にmongodbのバージョンを合わせてください
可能ならGrowiのバージョンも合わせてください

引越し先のec2インスタンスに先ほどのarchiveをupload

rsync -avz -e "ssh -i your-new-ec2.pem" ~/mongodb.archive ubuntu@xx.yyy.zzz.zzz:~

upload先のec2でDocker上のmongodbにコピー

sudo docker cp mongodb.archive growi_mongo_1:/

dropオプションで完全に置き換え

sudo docker exec -d growi_mongo_1 mongorestore --drop --archive=mongodb.archive

その後docker compose stopしてdocker compose up -dで再起動しましょう。

注意:検索が破損していることがあるので新しいサイトでElasticsearch 管理からインデックスのリビルドを行なってください。

定期バックアップについて

ここに書いてある通りです。

https://zenn.dev/nekoniki/articles/042bb1790b222c

{コンテナ名}はデフォルトで growi_mongo_1です。

docker exec {mongodb コンテナ名} mongodump --archive=mongodb.archive --quiet
docker cp {mongodb コンテナ名}:/mongodb.archive /opt/docker/growi/backup/growi_`date "+%Y%m%d"`.archive
find /opt/docker/growi/backup -mtime +7 | xargs rm -rf
rsync --delete -av /opt/docker/growi/backup/ {マウント先パス}

大体のwikiで困る全文検索について

elastic searchが内部で動いているので、かなり良い精度で検索が効きます。
よって階層構造が多少適当でも、ナレッジを検索して見つける、は実用的です。

少なくとも ファイル名とフォルダ階層だけを頼りにファイルサーバを掘るより65535倍くらいはマシ です。

セキュリティ監査でアレコレ言われるだるいやつの検証

Growiって監査ログって出せるの?

出せます。上で書いた通り

environment:
 #ここに色々設定がある
 - AUDIT_LOG_ENABLED = true #これでログを吐きます

うっかり覗き見されない?例えば画像のpermalinkを知ってたらアクセスされるとか

少なくともmongoDBにAttachment(画像ファイルやzip)を直接保存するようにしている状態では、画像ファイルやzipだけのURLを知っていても未ログインではアクセスできず、ログインページにリダイレクトされます。

知らない人がユーザで紛れ込んできたら怖いんだけど

特定のメールアドレス(例: @example.com )以下の人のみユーザ登録を受け付け、などを管理者は設定できます。他にもGoogle連携やLDAP連携 なども使えるようです。

GrowiにMicrosoft EntraIDでSAMLログインする
https://qiita.com/sugitaku03031/items/3eb8d70c5421f76a6ddd

  • Microsoft Entra ID (P1,P2)が必要
    • P1は月980円/人程度

偉い人、あるいはグループ限定のアクセス権限って作れるの?予算とか見せたくないけど…

いけます。社員限定、みたいなグループを作ることができます。
親子構造を設定できるので
全体->社員限定->役員限定

などの公開設定範囲指定も可能です。

共有リンクで覗き見されない??

管理者は共有リンクの一覧が取得できます。また、管理者はリンクのシェアを不許可に変更できます。
(個人的には設定で 共有リンク自体を不許可 にしちゃっても良いかもって思いました。後述しますがこの設定で建てたGrowiは画像ファイルが共有リンク経由だと見えないので)

逆に、出来ない(不便だ)と思われることのメモ

共有リンクによるシェアがあまり現実的ではない

埋め込み画像が読めないです。
PDF変換の実装を待ちましょう。(もしくはブラウザからpdf印刷)
https://github.com/weseek/growi/pull/9199

また、共有リンク経由のシェアで読む人にもフォルダ階層が伝わってしまうので、例えばプロジェクト名などの機微情報が意図せず露見する可能性があります。
例えば「お前の母ちゃんデベソ」などが露見します。

記事の外部サービスへの便利エクスポートがない

例えば売上が100000億円になったので、お金持ちっぽくConfluenceに引越したいな!!と思った時に不便かもしれません。
(それでも素のmdなのでまだマシな方だとは思います)

Discussion