EC2のAmazonLinuxにQiitaライクな情報共有サービス「Knowledge」を立ち上げる

# 目的

社内の情報共有に、Qiita:Teamはちょっとお高いからもっと気軽に始められる[Knowledge](https://support-project.org/knowledge_info/index)を作ってみよう、というところ。

# 背景

実は半年ぐらい使っていたのですが、個人サーバに作った結果、誤って消してしまう、かつバックアップも無いという事態に陥り、ちゃんと作り直すことに。。。

# 構成

|ソフトウェアとか|バージョン|その他|
|:--|:--|:--|
|OS|AmazonLinux|Amazon Linux AMI 2016.09.0.20160923 x86_64 HVM |
|Java|1.8.0|yumベース|
|Tomcat|8.0|yumベース|
|Knowledge|1.6.0|2016/10/27時点ではpre-release4でした|
|PostgreSQL|9.5.4|Knowledgeのデータ保管用|
※Knowledgeの管理画面上、PostgreSQLのドライバーが`9.3`となっていますが、`9.5`でも動きました

# 導入手順

## １．AmazonLinux

改めて言うことも無いので、ポイントだけ。

* AWSの管理コンソールから最新のAmazonLinux用AMIを選択してポチポチやる
* 今回は`t2.micro`、ストレージは`20GB`に設定
* セキュリティーグループはhttpの`80`だけ全解放（とりあえずIP制限等無し）
* 消してしまうと怖いから`削除保護`を有効にしておく
* タイムゾーンは日本に変更しておく
* EIPをセット

## ２．Knowledgeのインストール

作業は基本的に`ec2-user`で行います。

### Java/Tomcatのインストール

* 標準では`1.7`が入っているが、Java version 8 以降が推奨されているので更新する

```shell-session
$ sudo yum list installed |grep java
java-1.7.0-openjdk.x86_64             1:1.7.0.111-2.6.7.2.68.amzn1 installed    
javapackages-tools.noarch             0.9.1-1.5.amzn1              installed    
tzdata-java.noarch                    2016g-2.64.amzn1             @amzn-updates
```

* 基本は`yum`ベースとし、2016年10月27日時点で安定版をインストール対象とする
* Java : `JDK1.8`
* Tomcat : `8.0.36`
* 念のため、`yum search java`で最新版を確認
* alternativesコマンドを使い、Javaのバージョンを変更

```shell-session
$ sudo yum -y update
$ yum search java|grep openjdk
$ sudo yum -y install java-1.8.0-openjdk-devel tomcat8
$ sudo alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

Enter to keep the current selection[+], or type selection number: 2
$ java -version
openjdk version "1.8.0_101"
OpenJDK Runtime Environment (build 1.8.0_101-b13)
OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)
$ tomcat8 version
Server version: Apache Tomcat/8.0.36
Server built:   Aug 12 2016 18:14:42 UTC
Server number:  8.0.36.0
OS Name:        Linux
OS Version:     4.4.19-29.55.amzn1.x86_64
Architecture:   amd64
JVM Version:    1.8.0_101-b13
JVM Vendor:     Oracle Corporation
```

### Knowledgeのデプロイ

* Tomcatの初期設定で、`/var/lib/tomcat8/webapps`がデフォルトディレクトリ
* デフォルトだと`8080`ポートなので、`80`ポートに変更
* 80ポートでリクエストされたものを、8080ポートで待機しているTomcatにルーティングし、proxyPort属性を追加
* Tomcatを自動起動

```diff
$ sudo vi /etc/tomcat8/server.xml
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
-               redirectPort="8443" />
+               redirectPort="8443" 
+               proxyPort="80" />
$ sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
$ sudo /sbin/service iptables save
$ sudo service tomcat8 start
$ sudo chkconfig tomcat8 on
```

```shell-session
$ cd /var/lib/tomcat8/webapps
$ sudo wget https://github.com/support-project/knowledge/releases/download/v1.6.0pre4/knowledge.war
$ sudo service tomcat8 start
```

## ３．初期セットアップ

* ブラウザに`http://[[EC2のEIP]]/knowledge/`でアクセス
* 公式サイトの[手順](https://support-project.org/knowledge_info/open.manual/page/setup)に従い、初期セットアップ


## ４．PostgreSQLへの移行

* デフォルトのH2DatabaseからPostgreSQLへ移行する（公式サイトの推奨設定）
* 自動起動をOn

```diff
$ sudo yum install -y postgresql95 postgresql95-server postgresql95-devel postgresql95-contrib
$ psql --version
psql (PostgreSQL) 9.5.4
$ sudo service postgresql95 initdb
Initializing database:                                     [  OK  ]
$ sudo chkconfig postgresql95 on
$ sudo service postgresql95 start

#postgresユーザのパスワードを変更（今回はとりあえずパスワードも`postgres`にしましたが、適宜変えてください）
$ sudo passwd postgres
#環境変数を変更
$ sudo service postgresql95 stop
$ sudo usermod -d /var/lib/pgsql95 postgres
$ sudo grep postgres /etc/passwd
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql95:/bin/bash
$ su - postgres
$ vi /var/lib/pgsql95/.bash_profile 
[ -f /etc/profile ] && source /etc/profile

- PGDATA=/var/lib/pgsql93/data
+ PGDATA=/var/lib/pgsql95/data
export PGDATA
$ exit
$ sudo service postgresql95 start
```

* Knowledge用接続設定

```diff
$ su - postgres
$ vi /var/lib/pgsql95/data/postgresql.conf
- #listen_addresses = 'localhost'         # what IP address(es) to listen on;
+ listen_addresses = '*'         # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
- #port = 5432                            # (change requires restart)
+ port = 5432                            # (change requires restart)
$ vi /var/lib/pgsql95/data/pg_hba.conf
#以下の通り設定
- local   all             all                                     peer
+ local   all             all                                     md5
 host    all             all             127.0.0.1/32            trust
$ exit
$ sudo service postgresql95 restart

#Knowledge用DB作成
$ su - postgres
createdb knowledge
```

* Knowledge画面からPostgreSQLの設定
  1. Knowledgeに管理者ユーザでログイン
  2. 右上のユーザボタンから「システム設定」を選択
  3. 「データベースの接続先変更」を選択
  4. 「org.postgresql.Driver(9.3-1103-jdbc41)」を選択
  5. 以下の通り設定し、保存を押下  

|項目|設定値|備考|
|:--|:--|:--|
|URL|jdbc:postgresql://localhost:5432/knowledge|-|
|user|postgres|-|
|password|postgres|※適宜正しい値を設定してください|
|schema|public|-|
|max connection|0|Knowledgeのデフォルト値|
|auto commit|false|Knowledgeのデフォルト値|

* 「組み込みDBのデータをカスタム設定のDBへコピー」を実行

# バックアップ設計

* とりあえず手動で`pg_dump`を取得し、別途アタッチしたEBSをスナップショット保管
* [この辺りの記事](http://qiita.com/awakia/items/991d4a35aabcdf4c4990)を参考に別途実施・・・したい


これで使えるようになりました！！
あとはバックアップと、EIPは格好悪いから、専用のドメインを割り当てようかと。
気が向いたら更新します。

# 参考にさせていただいたサイト

* [Knowledge公式マニュアル](https://support-project.org/knowledge_info/open.manual/index)
* [Tomcatサーバに80番ポートでアクセスする。](http://blog.katty.in/2477)
* [Amazon LinuxでJava8/Tomcat8の環境を構築する](http://dev.classmethod.jp/cloud/aws/java8_tomcat8_on_amazon_linux/)
* [Install PostgreSQL on AWS EC2(Amazon Linux AMI 2013.03.1)](http://dev.classmethod.jp/cloud/aws/install-postgresql-on-aws-ec2/)
* [AWSでPostgreSQLサーバーを作る](http://qiita.com/awakia/items/991d4a35aabcdf4c4990)