CentOS8 にPleasanter With PostgreSQLをインストールしてみる。

# CentOS8 に Pleasanter with PostgreSQLをインストール

公式の手順ではCentOS7ですが、CentOS8でも普通に動きました。

[参考）公式のアナウンス：PostgreSQL対応版をリリースいたしました。](https://pleasanter.org/archives/7155)

## 条件的には問題なさそう

|必須ソフト|指定バージョン|CentOS8対応状況|
|:--|:--|:--|
|PostgreSQL|12.x|対応(標準リポジトリは10.x)|
|.NetCore|3.1|[対応](https://docs.microsoft.com/ja-jp/dotnet/core/install/linux-package-manager-centos8)|

## .NetCore SDK 3.1のインストール

標準リポジトリに含まれている為、dnfでインストールするだけです。

参考）　[CentOS 8 パッケージ マネージャー - .NET Core をインストールする](https://docs.microsoft.com/ja-jp/dotnet/core/install/linux-package-manager-centos8)

```shell
[user01@cent8 ~]$ sudo dnf install -y dotnet-sdk-3.1
```

## グラフィックサブシステム GDI+ のインストール

epelリポジトリからGDI+をインストールします。

```shell
[user01@cent8 ~]$ sudo yum install -y epel-release
[user01@cent8 ~]$ sudo yum install -y libgdiplus
```

## PostgreSQLのインストール

### PostgreSQL インストール

指定バージョンを利用する為、PostgreSQL公式サイトからインストールします。
標準のPostgreSQLモジュールを無効化しないと、PostgreSQL12をインストール出来ない点に注意してください。

```shell
[user01@cent8 ~]$ sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
[user01@cent8 ~]$ sudo dnf -qy module disable postgresql
[user01@cent8 ~]$ sudo dnf install -y postgresql12-server postgresql12-contrib
```

### PostgreSQL DB初期化

* encodeing：UTF8
* Locale：ja_JP.utf8
* AUTH：md5
* 初期化中に新規Superuserへのパスワード付与：実行する (後の手順で参考になるように、ここでは P@ssw0rd に設定しました)

```shell
[user01@cent8 ~]$ sudo su - postgres -c '/usr/pgsql-12/bin/initdb -E UTF8 --locale=ja_JP.utf8 -A md5 -W'
データベースシステム内のファイルの所有者はユーザ"postgres"となります。
このユーザをサーバプロセスの所有者とする必要があります。

データベースクラスタはロケール"ja_JP.utf8"で初期化されます。
initdb: could not find suitable text search configuration for locale "ja_JP.utf8"
デフォルトのテキスト検索構成は simple に設定されます。

データベージのチェックサムは無効です。

新しいスーパユーザのパスワードを入力してください:
再入力してください:

ディレクトリ/var/lib/pgsql/12/dataの権限を設定しています ... ok
サブディレクトリを作成しています ... ok
動的共有メモリの実装を選択しています ... posix
デフォルトのmax_connectionsを選択しています ... 100
デフォルトの shared_buffers を選択しています ... 128MB
selecting default time zone ... Asia/Tokyo
設定ファイルを作成しています ... ok
ブートストラップスクリプトを実行しています ... ok
ブートストラップ後の初期化を実行しています ... ok
データをディスクに同期しています ... ok

成功しました。以下のようにしてデータベースサーバを起動することができます:

    /usr/pgsql-12/bin/pg_ctl -D /var/lib/pgsql/12/data -l ログファイル start

[user01@cent8 ~]$
```

### ログ出力フォーマット設定

ログエントリの先頭に記録される情報を公式サイトのインストール手順に合わせて変更します。

参考）[公式：Pleasanter with PostgreSQLをCentOS7にインストールする](https://pleasanter.net/fs/publishes/1381104/edit)

```shell
[user01@cent8 ~]$ sudo vi /var/lib/pgsql/12/data/postgresql.conf
    510 #log_error_verbosity = default          # terse, default, or verbose messages
    511 #log_hostname = off
    512 ###log_line_prefix = '%m [%p] '         # special values:
    513 log_line_prefix = '[%t]%u %d %p[%l] '           # special values:
    514                                         #   %a = application name
    515                                         #   %u = user name
[user01@cent8 ~]$
```


### PostgreSQLの起動

```shell
[user01@cent8 ~]$ sudo systemctl --now enable postgresql-12
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql-12.service → /usr/lib/systemd/system/postgresql-12.service.
[user01@cent8 ~]$
```

## Pleasanterのインストール

### パッケージの入手・展開

```shell
[user01@cent8 ~]$ wget --content-disposition https://pleasanter.org/download/6475/
[user01@cent8 ~]$ sudo mkdir /web
[user01@cent8 ~]$ sudo unzip -q -d /web Pleasanter.NetCore_1.1.0.1.zip
```

### Pleasanter用DBの構成

* 設定ファイルへのスーパーユーザパスワードの設定(5行目のPWD=に設定します)
* CodeDefinerの実行

```shell
[user01@cent8 ~]$ sudo vi /web/pleasanter/Implem.Pleasanter/App_Data/Parameters/Rds.json
      1 {
      2     "Dbms": "PostgreSQL",
      3     "Provider": "Local",
      4     "TimeZoneInfo": "Asia/Tokyo",
      5     "SaConnectionString": "Server=localhost;Database=postgres;UID=postgres;PWD=P@ssw0rd",
      6     "OwnerConnectionString": "Server=localhost;Database=#ServiceName#;UID=#ServiceName#_Owner;PWD=SetAdminsPWD",
      7     "UserConnectionString": "Server=localhost;Database=#ServiceName#;UID=#ServiceName#_User;PWD=SetUsersPWD",
      8     "SqlCommandTimeOut": 600,
      9     "MinimumTime": 3,
     10     "DeadlockRetryCount": 4,
     11     "DeadlockRetryInterval": 1000
     12 }
[user01@cent8 ~]$  
```

```shell
[user01@cent8 ~]$ cd /web/pleasanter/Implem.CodeDefiner
[user01@cent8 Implem.CodeDefiner]$ sudo dotnet Implem.CodeDefiner.NetCore.dll _rds


〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

<SUCCESS> Starter.ConfigureDatabase: Database configuration has been completed.
<SUCCESS> Starter.Main: All of the processes have been completed.
[user01@cent8 Implem.CodeDefiner]$
```

## PostgreSQL 全文検索モジュールインストール

```shell
[user01@cent8 Implem.CodeDefiner]$ sudo su - postgres
[postgres@cent8 ~]$ psql
ユーザ postgres のパスワード:
psql (12.3)
"help"でヘルプを表示します。

postgres=# \c "Implem.Pleasanter";
データベース"Implem.Pleasanter"にユーザ"postgres"として接続しました。
Implem.Pleasanter=# CREATE EXTENSION pg_trgm;
CREATE EXTENSION
Implem.Pleasanter=# exit
[postgres@cent8 ~]$ exit
ログアウト
[user01@cent8 Implem.CodeDefiner]$
```

## Pleasanter 起動確認

### コマンドラインからの起動

この操作だと、フォアグラウンドで動作する為起動後プロンプトが返ってきません。
これは想定通りの動作です。

```shell
[user01@cent8 Implem.CodeDefiner]$ cd ../Implem.Pleasanter/
[user01@cent8 Implem.Pleasanter]$ pwd
/web/pleasanter/Implem.Pleasanter
[user01@cent8 Implem.Pleasanter]$ sudo dotnet Implem.Pleasanter.NetCore.dll
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {17c11830-69a5-4eff-809f-207772878318} may be persisted to storage in unencrypted form.
warn: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Address family not supported by protocol'.
```

### curlコマンドでの応答確認

新しいターミナルを開いて```curlコマンド```を使って応答の確認を行います。
CentOS上でFirefoxが利用できる場合、Firefoxで```http://localhost:5000/```にアクセスして確認する事もできます。

```shell
[user01@cent8 ~]$ curl -v http://localhost:5000/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Sun, 07 Jun 2020 07:49:42 GMT
< Server: Kestrel
< Content-Length: 0
< Location: http://localhost:5000/users/login?ReturnUrl=%2F
<
* Connection #0 to host localhost left intact
[user01@cent8 ~]$
```

### 動作確認終了

curlコマンドまたはFirefoxで動作確認ができたら、Pleasanterを起動したターミナルで```Ctrl+C```を押してPleasanterを終了します。

## Pleasanterサービス用スクリプトの作成

### サービススクリプトの作成／登録

systemdでサービスを管理する為、```/etc/systemd/system/pleasanter.service```を作成します。
作成後```systemctl daemon-reload```を実行しsystemdに反映させます。

```shell
[user01@cent8 ~]$ sudo vi /etc/systemd/system/pleasanter.service
[Unit]
Description = Pleasanter
Documentation =
Wants=network.target
After=network.target

[Service]
ExecStart = /usr/bin/dotnet Implem.Pleasanter.NetCore.dll
WorkingDirectory = /web/pleasanter/Implem.Pleasanter
Restart = always
RestartSec = 10
KillSignal=SIGINT
SyslogIdentifier=dotnet-pleasanter
User = root
Group = root
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy = multi-user.target
[user01@cent8 ~]$ sudo systemctl daemon-reload
[user01@cent8 ~]$ systemctl status pleasanter.service
● pleasanter.service - Pleasanter
   Loaded: loaded (/etc/systemd/system/pleasanter.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
[user01@cent8 ~]$
```

### Pleasanterサービスの起動

```shell
[user01@cent8 ~]$ sudo systemctl --now enable pleasanter
[user01@cent8 ~]$ systemctl status pleasanter
● pleasanter.service - Pleasanter
   Loaded: loaded (/etc/systemd/system/pleasanter.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-06-07 16:52:34 JST; 43s ago
 Main PID: 12488 (dotnet)
    Tasks: 21 (limit: 24993)
   Memory: 269.6M
   CGroup: /system.slice/pleasanter.service
           └─12488 /usr/bin/dotnet Implem.Pleasanter.NetCore.dll

 6月 07 16:52:34 cent8.example.co.jp systemd[1]: Started Pleasanter.
 6月 07 16:52:37 cent8.example.co.jp dotnet-pleasanter[12488]: warn: Microsoft.AspNetCore.Server.Kestrel[0]
 6月 07 16:52:37 cent8.example.co.jp dotnet-pleasanter[12488]:       Unable to bind to http://localhost:5000 on the IPv6 loopback int>
[user01@cent8 ~]$
```

## Firewallの設定

外部からhttpsへのアクセスを許可するよう設定します。

```shell
[user01@cent8 ~]$ sudo firewall-cmd --permanent --zone=public --add-service=https
success
[user01@cent8 ~]$ sudo firewall-cmd --reload
success
[user01@cent8 ~]$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: cockpit dhcpv6-client https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

[user01@cent8 ~]$
```

## SELinux設定変更

Nginxからpleasanterへの通信を許可するための設定を行います。
面倒だったら、SELinuxを無効にしても良いかしれません。

**必要な制限のみ解除**

```shell
[user01@cent8 ~]$ sudo setsebool -P httpd_can_network_connect 1
```

**SELinux自体を無効化する場合**

setenforeで一時的に無効化し、設定ファイルの変更で次回起動時も無効化されたままに出来ます。

```shell
[user01@cent8 ~]$ sudo setenforce 0
[user01@cent8 ~]$ sudo vi /etc/sysconfig/selinux
      3 # SELINUX= can take one of these three values:
      4 #     enforcing - SELinux security policy is enforced.
      5 #     permissive - SELinux prints warnings instead of enforcing.
      6 #     disabled - No SELinux policy is loaded.
      7 ##SELINUX=enforcing
      8 SELINUX=disabled

[user01@cent8 ~]$   
```

## Nginxを使ったリバースプロキシを構成（https対応）

利用者の多いchromeでもテスト出来るように、chromeに対応したテスト用証明書を作成します。
※実際に運用する場合は正規の証明書を取得しましょう。

### サーバ証明書の作成

mkcertを使ってテスト用証明書を作成します。
```pleasanter.example.co.jp```　と入力している部分は、実際のホスト名に置き換えてください。
※ mkcert -install 実行時に、テスト用CA証明書がサーバ上の証明書ストアに配置されます。
  この為、サーバ上のブラウザでアクセスすると、証明書の警告が出ませんがこのサーバ上だけでの事です。
  本番運用で利用できる証明書ではありませんので注意しましょう。

mkcertを利用するためにnss-tools,golangが必要です。
通常nss-toolsは導入されているので、golangとmkcertの追加導入が必要です。
なお、標準リポジトリのgolangは古い為、公式から導入します。

* golangの導入

```shell
[user01@cent8 ~]$ wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz
[user01@cent8 ~]$ sudo tar -C /usr/local -xzf go1.14.4.linux-amd64.tar.gz
[user01@cent8 ~]$ export PATH=$PATH:/usr/local/go/bin
```

* mkcertの導入と証明書の作成

```shell
[user01@cent8 ~]$ git clone https://github.com/FiloSottile/mkcert && cd mkcert
[user01@cent8 mkcert]$ go build -ldflags "-X main.Version=$(git describe --tags)"
[user01@cent8 mkcert]$ ./mkcert -install
Created a new local CA at "/home/user01/.local/share/mkcert" 💥
The local CA is now installed in the system trust store! ⚡️
The local CA is now installed in the Firefox and/or Chrome/Chromium trust store (requires browser restart)! 🦊

[user01@cent8 mkcert]$
[user01@cent8 mkcert]$ ./mkcert pleasanter.example.co.jp
Using the local CA at "/home/user01/.local/share/mkcert" ✨

Created a new certificate valid for the following names 📜
 - "pleasanter.example.co.jp"

The certificate is at "./pleasanter.example.co.jp.pem" and the key at "./pleasanter.example.co.jp-key.pem" ✅

[user01@cent8 mkcert]$
[user01@cent8 mkcert]$ sudo cp pleasanter.example.co.jp* /etc/pki/tls/certs/
```

### NginXリポジトリ追加

Nginx公式サイトの手順を基にリポジトリを追加します。
[Nginx : Installation instructions](http://nginx.org/en/linux_packages.html#RHEL-CentOS)

```shell
[user01@cent8 mkcert]$ sudo vi /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[user01@cent8 mkcert]$ 
```

### Nginxインストール

```shell
[user01@cent8 mkcert]$ sudo yum install -y nginx
```

### DHE用ファイルの作成

```shell
[root@cent8 mkcert]# sudo openssl dhparam -out /etc/pki/tls/dh2048.pem -outform PEM 2048
```

### リバースプロキシの設定／起動

```shell
[user01@cent8 mkcert]$ sudo vi /etc/nginx/conf.d/reverse-proxy.conf
server {
    listen        443 ssl;
    server_name   pleasanter.example.co.jp;
    keepalive_timeout 60;
    root /usr/share/nginx/html;
    server_tokens off;

    ssl_protocols  TLSv1.2;
    ssl_ciphers    HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_certificate  /etc/pki/tls/certs/pleasanter.example.co.jp.pem;
    ssl_certificate_key  /etc/pki/tls/certs/pleasanter.example.co.jp-key.pem;
    ssl_dhparam /etc/pki/tls/dh2048.pem;
    ssl_session_cache   shared:SSL:10m; ## 1MB = about 4000 sessions
    ssl_session_timeout 10m;

    location / {
	proxy_set_header Host $host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-Proto https;
	proxy_set_header X-Forwarded-Host $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

	proxy_redirect http:// https://;

	proxy_pass http://localhost:5000;
    }
}
[user01@cent8 mkcert]$ sudo systemctl enable --now nginx
```


### 初期ID／パスワード

|設定項目|初期値|備考|
|:-:|:-:|:-:|
|管理アカウント |administrator | |
|初期パスワード| pleasanter | 初回ログイン時に変更を求められます|

<img width="533" alt="スクリーンショット 2020-06-06 21.00.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560759/09af991b-7a70-6f90-5967-adea5e4a1e25.png">

## これからやる事

* リマインダー設定
* メール送信テスト