CentOS7にRedmine4.1をインストールする

[この記事の4.1版です。](https://qiita.com/bikun_bikun/items/30951573fc900d78d0c9)

## 前提条件
- ruby 2.6.5
- redmine 4.1
- PostgreSQL 12

## 下準備

### DeveloperToolのインストール
``` sh
yum -y groupinstall "Development Tools"
```

### PostgreSQL12のインストール
#### PostgreSQL12のインストール

``` sh
# PostgreSQLのyumリポジトリをインストール
yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# postgreSQLのインストール
yum -y install postgresql12-server postgresql12-contrib postgresql12-devel

# PostgreSQLの自動起動設定
systemctl enable postgresql-12.service

# PostgreSQLの初期設定
PGSETUP_INITDB_OPTIONS="-E UTF8 --no-locale" /usr/pgsql-12/bin/postgresql-12-setup initdb

```

#### PostgreSQL Userへ移動し設定を行う
``` sh
su - postgres

# profileの修正
vi /var/lib/pgsql/.pgsql_profile
```

下記内容を追記

``` sh
PATH=/usr/pgsql-12/bin:$PATH
export PATH
```

ここまでできたら一度postgres userから抜け、再度postgres userへ移動する
※プロファイルの読み込みがされるか確かめるためです。

```sh
exit
su - postgres
```

#### ユーザとデータベールの作成

``` sh
# ユーザの作成
createuser --login --pwprompt 【ユーザ名】
# パスワード入力を求められるため、入力する。

# DBの作成
createdb --owner=【ユーザ名】 【DB名】
```

#### アクセス許可設定の変更

アクセス許可ファイルを編集します。
※今回は外部からのアクセスは無し＆Redmineからのアクセスを行うため、ID,Password認証のみ許可
※Unix DomainSocketの場合はpeerとする

``` sh
vi /var/lib/pgsql/12/data/pg_hba.conf
```

修正内容は下記

```
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             postgres                                peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5
```

設定変更のリロードを行う

``` sh
pg_ctl reload
```

※ログの設定等はお好みで設定してください。


### ruby2.6.5のインストール

``` sh
# rubyのダウンロード
curl -O https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.gz

# 解凍
tar xvf ruby-2.6.5.tar.gz

# 解凍先へ移動
cd ruby-2.6.5

# ドキュメントをインストールしないように修正
./configure --disable-install-doc

# コンパイル
make

# インストール
make install

# bundlerのインストール
gem install bundler -N
```

### nginxのインストール

``` sh
# yumリポジトリの追加
yum -y install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

# リポジトリのアップデート
yum -y update nginx-release-centos

# nginxのインストール
yum -y --enablerepo=nginx install nginx
```

## redmineのインストール

### ソースの取得
``` sh
# インストール用のディレクトリの用意
cd /usr/local/src

mkdir redmine

# redmineのクローン
svn co http://svn.redmine.org/redmine/branches/4.1-stable ./4.1
```

### 設定ファイルの準備

通常、クローンしたredmineの配下にあるconfigディレクトリ内のファイルをそのままリネームして使いますが、今回はupdateしやすいように別の場所で管理することにします。

``` sh
# '/usr/local/src/redmine'配下にバージョン番号でクローンしているため、configディレクトリを外だしする。

pwd
# '/usr/local/src/redmine'が表示される状態であることを確認

mkdir config
mkdir storage

ls -la
# 下記ディレクトリが出てくる
# 4.1
# config
# storage

# 設定ファイルをコピーしてリネームする
cp -p /usr/local/src/redmine/4.1/config/database.yml.example /usr/local/src/redmine/config/database.yml
cp -p /usr/local/src/redmine/4.1/config/configuration.yml.example /usr/local/src/redmine/config/configuration.yml
```
### 設定ファイルの編集

database.ymlの変更

``` sh
vi /usr/local/src/redmine/config/database.yml
```

下記内容とする

``` yml
production:
  adapter: postgresql
  database: 【作成したDB名】
  host: localhost
  username: 【設定したユーザ名】
  password: "【設定したパスワード】"
  # Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7
  encoding: utf8
```

configuration.ymlの修正

``` sh
vi /usr/local/src/redmine/config/configuration.yml
```

下記Key項目の設定を行う

``` yml
# sendgridの設定
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: "smtp.sendgrid.net"
      port: 587
      authentication: :login
      domain: '【Redmineのドメイン名】'
      user_name: '【sendgridのユーザ名】'
      password: '【sendgridのパスワード】'

# redmineの添付ファイルなどを格納するディレクトリの設定
  attachments_storage_path: /usr/local/src/redmine/storage

# 日本語フォント用
  minimagick_font_path: /usr/share/fonts/ipa-pgothic/ipagp.ttf

```

### 設定ファイルの参照設定

``` sh
ln -s /usr/local/src/redmine/config/database.yml /usr/local/src/redmine/4.1/config/database.yml
ln -s /usr/local/src/redmine/config/configuration.yml /usr/local/src/redmine/4.1/config/configuration.yml

```

### 初期構築コマンドの実行

``` sh
bundle config set path 'vendor/bundle'
bundle config set without 'development test'
bundle install
```

※pgがインストールできないと言われたらpostgresqlが標準ではなく12を入れているせいかと思われます。
※下記コマンドでインストールしてください。

``` sh
bundle config build.pg --with-pg-config=/usr/pgsql-12/bin/pg_config --with-pg-lib=/usr/pgsql-12/include/libpq-fe.h --with-opt-dir=/usr/pgsql-12
```

### 続きの設定コマンド

``` sh
# セッション改ざん防止用キーの作成
bundle exec rake generate_secret_token

# DBのMigration実行
RAILS_ENV=production bundle exec rake db:migrate

# デフォルトデータ登録
RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data
```

### 動作確認

一時的にfirewallのportを開ける

``` sh
# 一時的に3000ポートを開放
firewall-cmd --add-port=3000/tcp --zone=public

# ビルドインサーバの立ち上げ
ruby bin/rails server webrick -e production

# ブラウザからhttp://ホストのIP:3000へアクセスし、redmineページが表示されることを確認。

# リロード処理にてポートを閉じる
firewall-cmd --reload
```

### redmineの実行用シンボリックリンクの作成
redmineのversion upをしやすくするために、実行用のシンボリックリンクを作成します。

``` sh
ln -s /usr/local/src/redmine/4.1 /var/lib/redmine
```

## Unicornのインストール
### インストールと動作確認

Gemfileの最後にunicornを追記する

```
gem "unicorn"
```

``` sh
# unicornのインストール
bundle update

# 一時的に3000番ポートを開放する
firewall-cmd --add-port=3000/tcp --zone=public

# unicornでwebサーバを立ち上げる
bundle exec unicorn_rails -l 3000 -E production

# ブラウザから先程同様動作確認をする

# ポートを閉じるためにリロードする
firewall-cmd --reload

```

### Service登録用のファイルを作成
こちらも使いまわしができるようにconfigを作成したディレクトリに入れます。

``` sh
vi /usr/local/src/redmine/config/unicorn.rb
```

``` unicorn.rb
# -*- coding: utf-8 -*-
# Unicorn設定ファイル
# 次のURLのサンプルをベースにしている。
# http://unicorn.bogomips.org/examples/unicorn.conf.rb

# 専用サーバーであればコアにつき1個以上を指定する。
worker_processes 2

# リクエスト待ち受け口、TCPとUNIXドメインとが指定可能。
listen "/var/lib/redmine/tmp/sockets/redmine.sock", :backlog => 32
# listen 8282, :tcp_nopush => true

# タイムアウト秒数
timeout 30

# 稼働中のプロセスのPIDを書いておくファイル。
pid "/var/lib/redmine/tmp/pids/redmine.pid"

# デーモンで起動すると標準出力／標準エラー出力が/dev/nullになるので、
# それぞれログファイルに出力する。
# /var/logで一元管理する場合はフルパスで記載、その場合は/var/log配下にunicornディレクトリを作っておく。
# 今回はredmineようなのでディレクトリ名はredmineとする。
stderr_path '/var/log/redmine/unicorn.stderr.log'
stdout_path '/var/log/redmine/unicorn.stdout.log'

# マスタープロセス起動時にアプリケーションをロードする(true時)。
# ワーカープロセス側でロードをしないのでメモリ消費、応答性良好になる。
# ただし、ソケットはfork後に開きなおす必要あり。
# HUPシグナルでアプリケーションはロードされない。
preload_app true

# unicornと同一ホスト上のクライアントとのコネクション限定で、維持されているかを
# アプリケーションを呼ぶ前にチェックする。
check_client_connection false

before_fork do |server, worker|
  # Railsでpreload_appをtrueにしているときは強く推奨
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  # Railsでpreload_appをtrueにしているときは必須
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection

  begin
    uid, gid = Process.euid, Process.egid
    # user, group = "redmine", "redmine"
    # ENV["HOME"] = "/home/redmine"
    target_uid = Etc.getpwnam(user).uid
    target_gid = Etc.getgrnam(group).gid
    worker.tmp.chown(target_uid, target_gid)
    if uid != target_uid or gid != target.gid
      Process.initgroups(user, target_gid)
      Process::GID.change_privilege(target_gid)
      Process::UID.change_privilege(target_uid)
    end
  rescue
    if RAILS_ENV = "development"
      STDERR.puts "could not change user, oh well"
    else
      STDERR.puts "could not change user, oh well"
      raise e
    end
  end
end
```

### Service起動用のファイルを作成

``` sh
vi /usr/lib/systemd/system/redmine.service
```

``` redmine.service
[Unit]
Description=Redmine Unicorn Server

[Service]
WorkingDirectory=/var/lib/redmine
Environment=RAILS_ENV=production
SyslogIdentifier=redmine
PIDFile=/var/lib/redmine/tmp/pids/unicorn.pid

ExecStart=/usr/local/bin/bundle exec "unicorn_rails -c /usr/local/src/redmine/config/unicorn.rb -E production" 
ExecStop=/usr/bin/kill -QUIT $MAINPID
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target
```

### Serviceの確認

``` sh
# 起動確認
systemctl start redmine

# 動作確認
systemctl status redmine

# こんな感じの出力になっていればOK
# systemctl status redmine
#● redmine.service - Redmine Unicorn Server
#   Loaded: loaded (/usr/lib/systemd/system/redmine.service; disabled; vendor preset: disabled)
#   Active: active (running) since Mon 2020-02-17 08:40:50 JST; 4s ago
# Main PID: 31165 (ruby)
#   CGroup: /system.slice/redmine.service
#           └─31165 ruby /usr/local/src/redmine/4.1/vendor/bundle/ruby/2.6.0/bin/unicorn_rails -c /usr/local/src/redmine/config/unicorn.rb -E production

```

## firewallの設定
http及びhttpsの許可設定を行います。

``` sh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
```

## nginxの設定
※ssl証明書はすでに準備済みとして先に進みます。
下記設定はLet's encryptを利用し、ssl証明書を取得しています。

### configファイルの作成

``` sh
vi /etc/nginx/conf.d/redmine.conf
```

``` redmine.conf
upstream redmine {
    server unix:/var/lib/redmine/tmp/sockets/redmine.sock;
}

server {
    listen 80;
    server_name 【youredmine.domain】;
    rewrite ^ https://$server_name$request_uri? permanent;
} 

server {
    listen       443 ssl;
    server_name  【youredmine.domain】;

    root /var/lib/redmine/public;

    ssl on;

    ssl_certificate /etc/letsencrypt/live/youredmine.domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/youredmine.domain/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets on;

    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

    ssl_prefer_server_ciphers on;

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/youredmine.domain/fullchain.pem;
    resolver 8.8.8.8;

    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';

    client_max_body_size 1G;

    access_log  /var/log/nginx/redmine.access.log;
    error_log /var/log/nginx/redmine.error.log;

    location / {
        try_files $uri/index.html $uri.html $uri @app;
    }

    location @app {
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_connect_timeout 60;
        proxy_read_timeout 60;
        proxy_send_timeout 600;
        proxy_pass http://redmine;
    }

    error_page 500 502 503 504 /500.html;

}
```

### nginxの起動

``` sh
systemctl start nginx
```

以上。
雑に書いたので間違ってるところがあったらご指摘ください。