Amazon ECS + RDS(PostgreSQL) で Qiita:Team の オープンソースクローン Knowledge(Docker版) を構築する

社内でナレッジ共有ができると、エンジニアやデザイナーが社外秘事項などを気にすることなくアウトプットできるというメリットがあります。筆頭サービスは Qiita:Team でしょう。Qiita と同じ使用感なので、書き手にとっては馴染み深いというメリットがあります。一方で、このようなサービスを使っていて、記事が充実しメンバーが増えてくるにつれ別の課題も浮上します。コストです。このあたりはおそらく正解というものはなく、試行錯誤して費用対効果を最大にしていくしかないのではないかと考えます。

本記事では、チーム内ナレッジ共有のための選択肢として、サーバーインストール型の Knowledge をAWS環境へ導入する手順を示します。Qiita:Team のオープンソースクローンであり、使い勝手も似ています。機能も十分。「とりあえずたてて使ってみたい」という方の参考になれば幸いです。

docker-knowledge

大きな戦略として、Amazon ECS を使います。アプリケーションやミドルウェアのインストールを省略するためです。Knowledgeそのものは Tomcat アプリケーションですが、ありがたいことに、docker-knowledge が用意されており、これを使えば Docker コンテナとして Knowledge を利用することが可能です。

また、データは永続化したいたいめ、RDSでPostgreSQLを構築します。もともとの Knowledge の想定としては、まずローカルDBで起動した後に、ブラウザから PostgreSQL へアクセス先を変更しつつデータ移行を行うというもののようです。今回は Amazon ECS でコンテナを起動した瞬間から RDS へアクセスさせたいため、Dockerfile に若干の修正を加えます。最終的には以下のような状態を目指します。

arc

構築手順です:

  1. Amazon RDS で PostgreSQL を作る
  2. Knowledge の Docker Image を作り、Amazon ECRにプッシュする
  3. Amazon ECS のタスク定義を作成する
  4. Amazon ECS のクラスターとサービスを作成する
  5. Route 53 で取得したドメインのゾーンを作成する
  6. 試す

バージョン情報

アプリケーション バージョン
knowledge v1.10.0

1. Amazon RDS で PostgreSQL を作る

特に難しいことはありませんが、スキーマやユーザー名などは knowledge にあわせておきます。今回はプロダクション運用のためのものではないのでテストモードで起動します。以下は設定例です。

rds1

rds2

PostgreSQLが作成されたことを確認したら、エンドポイント、ユーザー名、パスワードを控えておいて下さい。後の設定ファイルに記載します。

rds3

2. Knowledge の Docker Image を作り、Amazon ECRにプッシュする

データベース接続先の変更

まずはこちらのリポジトリをクローンしてください。デフォルトの状態では、ローカルのデータベースにアクセスするようです。volumes/knowledge/custom_connection.xmlでDB接続先設定をカスタマイズできるようですので、作成したPostgreSQLの情報を使ってこのファイルを編集します。

Dockerfile の編集

さきほど編集した custom_connection.xml が コンテナ起動時に適用されるようにします。

...
VOLUME [ "/root/.knowledge" ]
COPY ./volumes/knowledge/custom_connection.xml /root/.knowledge/
EXPOSE 8080
...

Docker Image の作成

編集が終わったら Docker Image を作成します。

pwd
~/path/to/docker-knowledge

docker build -t knowledge .

タグ付け、ECRへのプッシュ

AWS コンソールで Amazon ECS のページへアクセスし、「リポジトリ」を選択、新しいリポジトリを作成します。すると、作成したリポジトリへ Docker Image をプッシュする手順が載っていますので従いましょう。

ecr

作成したイメージが Amazn ECR に登録されます。

3. Amazon ECS のタスク定義を作成する

登録したイメージを使ったタスク定義を作成します。ポイントは以下です:

  • 動的ポートマッピングを利用できるようにする(EC2インスタンス1台あたりに複数の Dokcer コンテナを起動したい)
  • ロググループをあらかじめ作っておく

動的ポートマッピングを利用できるようにする

コンテナ側の設定で、ポートマッピングのホストポートを「0」にします。

task

ロググループをあらかじめ作っておく

ログを出したいのでロググループを作っておきます。最初、タスクが起動できずに、原因がわからなかったのですが、よく調べるとロググループをあらかじめ作っておかなければならないというエラーでした。

task2

4. Amazon ECS のクラスターとサービスを作成する

クラスターはコンテナが実行されるEC2インスタンス群を管理するもので、サービスは、タスク定義に対して実際にタスクを起動する戦略を決めます。ここでは、

  • ALB を使って Dockerコンテナに 動的ポートマッピングする
  • タスクを2つ(コンテナ2つ)起動する

よう、設定していきます。

ALB を作成する

サービスにALBを登録する形になるので、あらかじめALBを作成する必要があります。このあたりは ALB + ECS のパターンで、ターゲットグループにターゲットを登録しない状態 で作成します。

クラスターを作成する

ウィザードに従いインスタンスタイプ、ネットワーク設定を入力してください。

サービスを作成する

マネージメントコンソールで Amazon ECS の画面に戻り、クラスターの設定を開きます。その画面から新しくサービスを作ります。

  • タスクの数を「2」
  • ネットワーク構成で作成したALBおよびターゲットグループを指定

するようにしてください。

service

ここまで終わると、クラスター上に Docker コンテナが展開されていきます。

cluster

5. Route 53 で取得したドメインのゾーンを作成する

ここまでできたら、あとは 取得したドメインでアクセスできるようにするだけです。今回は お名前.com で適当なドメインを取得してきました。

Rotue 53 でゾーン設定を追加する

すると、ネームサーバが割り当てられるはずです。

route53

このネームサーバーを、お名前.com のネームサーバ情報として登録します。

onamae

更新して、しばらくまちます。

ALBへのエイリアスを追加する

knowledge.xxxx.xxxx というサブドメイン名で ALB へ飛ぶようにしましょう。Route53 で 「Create Record Set」を行います。

route532

これで、取得したドメインで ECS の Knowledge にアクセスできるはずです。

6. 試す

knowledge

ECS + RDS で Knowlege を構築することができました。

まとめ

AWS に Knowledge を構築するパターンは、 Qiita:Team などのナレッジ共有サービスを使う場合に比べ、以下のようなシーンで有利かもしれません。

  • 自社の GitHub Enterprise どをすでに持っており、AWSで運用している
  • 研究室で利用できるAWS環境があり、サーバ運用が可能な状態
  • 技術者の人数が増えており、今後も増加が予想され、サービス利用料金が増加する

「すでに AWS で社内向けサーバを構築している」か「ナレッジ共有は行いたいが、どうしてもコストを下げなければならない」に大別できそうです。このような課題に直面している方も、とりあえず構築してみたい方も、本記事の手順が参考になれば幸いです。

参考