カテゴリー
インフラ

CentOS7にRedmineをインストールする

はじめに

今回、WebサーバーにNginxを、アプリケーションサーバーにunicorn(+ Ruby on Rails + Redmine)を、データベースサーバーにMariaDBをそれぞれ採用して、CentOS7のインストールイメージminimalを使って構築したいと思います。 なお、アプリケーションサーバーの部分についてはWebサーバーやデータベースサーバーと同様に、systemctlコマンドで起動や停止ができるようにします。

ホストの準備

本環境をセットアップするホストを準備します。AWS EC2インスタンスを使用する場合と、オンプレミス環境で一から構築する場合を想定します。

OSインストールとホスト起動

AWS EC2向け

CentOS公式サイト ダウンロードページからISOファイルのファイル名を参照して最新の日付(YYMM)を確認します。 AWS マネジメントコンソールにサインインしてEC2ダッシュボード画面を表示します。インスタンス作成時に、AWS Marketplaceから「CentOS HVM」で検索すれば、最新のCentOS7を利用できます。

オンプレミス向け

CentOS公式サイト ダウンロードページからISOファイルをダウンロードします。OSインストーラーを起動してインストールします。

設定バックアップ用ディレクトリ作成

# mkdir -p /root/originalfiles

SELinux無効化

# setenforce 0
# cp /etc/sysconfig/selinux /root/originalfiles/etc__sysconfig__selinux
# vi /etc/sysconfig/selinux
# diff /root/originalfiles/etc__sysconfig__selinux /etc/sysconfig/selinux
7c7
< SELINUX=enforcing
---
> SELINUX=disabled

SSHサーバー追加

オンプレミス環境でminimalイメージからセットアップした場合、SSHサーバーがインストールされていませんので、TTY端末で下記コマンドを実行してインストールします。

# yum install openssh-server
# systemctl start sshd
# systemctl enable sshd

以降、手元のPCのSSH端末を使用してリモートで操作できるようになります。

postfixインストール

Redmineはチケットのステータスが変更されたときなど、メールで通知する機能があります。メールを送信できるようにするため、Postfixをインストールします。

パッケージインストール

# yum install postfix

設定調整

このホストからはメールを発送するだけですので、送り元となるサーバーのFQDNを指定するだけにします。

# cp /etc/postfix/main.cf /root/originalfiles/etc__postfix__main.cf
# vi /etc/postfix/main.cf
# diff /root/originalfiles/etc__postfix__main.cf /etc/postfix/main.cf
75c75
< #myhostname = host.domain.tld
---
> myhostname = redmine.example.com
98c98
< #myorigin = $myhostname
---
> myorigin = $myhostname

サーバー起動

# systemctl restart postfix
# systemctl enable postfix

メールテスト送信

実際にどのようにメールが発送されるか確認します。このホストのroot宛のメールはすべて普段使っているメールアドレス宛に転送するようにします。このコマンドを実行すると、送り主はroot@redmine.example.comとなっているはずです。以降、このホストのユーザー(Linuxユーザー)から発送されるメールの差出人は「@redmine.example.com」となります。

# echo 'myaddress@example.com' >> /root/.forward
# yum install mailx
# echo 'transport test from new redmine server' \
    | mail -s 'transport test' root

MariaDB5.5インストール

Redmineのユーザーデータを格納するデータベースサーバーをインストールします。

パッケージインストール

# yum install mariadb-server

設定調整

# cp /etc/my.cnf.d/server.cnf /root/originalfiles/etc__my.cnf.d__server.cnf
# vi /etc/my.cnf.d/server.cnf
# diff /root/originalfiles/etc__my.cnf.d__server.cnf /etc/my.cnf.d/server.cnf
9a10
> character-set-server = utf8
# cp /etc/my.cnf.d/client.cnf /root/originalfiles/etc__my.cnf.d__client.cnf
# vi /etc/my.cnf.d/client.cnf
# diff /root/originalfiles/etc__my.cnf.d__client.cnf /etc/my.cnf.d/client.cnf
7a8
> default-character-set = utf8

サーバー起動

# systemctl start mariadb
# systemctl status mariadb
# systemctl enable mariadb

Redmineアプリケーションサーバー構築

インストールドキュメントによると、Redmine3.4.3 (2017.10.21時点で最新の安定版)にはruby2.4、Rails4.2を使えばよさそうです。 Redmine、Ruby on Rails環境、unicornをすべて、アプリケーション実行用ユーザーapp-userで実行するようにします。

アプリケーションユーザー追加

# useradd app-user

ruby2.4インストール

ruby2.4はapp-userのユーザーローカル環境にセットアップして、OSの共通領域をクリーンに保つようにします。

ビルド環境インストール

# yum groupinstall "Development Tools"
# yum install openssl-devel readline-devel zlib-devel curl-devel libyaml-devel mariadb-devel ImageMagick ImageMagick-devel

rbenvセットアップ

# su - app-user
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv
$ src/configure && make -C src

$ vi ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH="$PATH:$HOME/bin"
PATH="$PATH:$HOME/.rbenv/bin"      ← この行を追記

export PATH
$ ~/.rbenv/bin/rbenv init

$ vi ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH="$PATH:$HOME/bin"
PATH="$PATH:$HOME/.rbenv/bin"

export PATH

eval "$(rbenv init -)"      ← この行を追記

app-user環境をリロードするため、一度ログアウトしてログインしなおします。type rbenvを実行すると、rbenv() の内容が表示されるようになります。

$ logout
# su - app-user
$ type rbenv
rbenv is a function
rbenv ()
{
    local command;
    command="$1";
    if [ "$#" -gt 0 ]; then
        shift;
    fi;
    case "$command" in
        rehash | shell)
            eval "$(rbenv "sh-$command" "$@")"
        ;;
        *)
            command rbenv "$command" "$@"
        ;;
    esac
}

ruby-buildプラグインインストール

Railsインストールのため、ruby-buildをインストールします。

$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Rubyインストール

利用できるRubyのバージョン一覧を確認します。

$ rbenv install -l

2.4.x のうち最新のものを指定してインストールします。

$ rbenv install 2.4.2

app-userがデフォルトで利用するrubyのバージョンを明示的に指定します。

$ rbenv global 2.4.2
$ ruby -v

Rails4.2インストール

railsのバージョン一覧を確認します。

$ gem list '^rails

rails 4.2.x のうち最新バージョンをインストールします。

$ gem install rails --version "~>4.2.0"

インストールされたrailsのバージョンを確認します。

$ rails --version

Redmine3.4インストール

データベースアカウント作成

$ mysql -u root
> CREATE DATABASE redmine CHARACTER SET utf8;
> CREATE USER 'redmine'@'localhost';
> GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost';
> QUIT;

パッケージインストール

$ mkdir ~/src
$ cd ~/src
$ curl -LO http://www.redmine.org/releases/redmine-3.4.2.tar.gz
$ tar fx redmine-3.4.2.tar.gz
$ logout
# cp -r /home/app-user/src/redmine-3.4.2 /var/lib/redmine
# chown -R app-user:app-user /var/lib/redmine

設定調整

Redmineがデータベースサーバーに接続できるようにします。

# su - app-user
$ cp /var/lib/redmine/config/database.yml.example /var/lib/redmine/config/database.yml
$ vi /var/lib/redmine/config/database.yml
$ diff /var/lib/redmine/config/database.yml.example /var/lib/redmine/config/database.yml

config/database.yml

9c9
<   username: root
---
>   username: redmine

Redmineがメールを発送する方法を指定します。今回はPostfixに対してsendmailコマンドで送るように設定します。

先の手順で、mailコマンドを使ってroot宛にメールの発送テストをしましたが、mailコマンドもsendmailコマンドを使用してメールを発送します。

$ cp /var/lib/redmine/config/configuration.yml.example /var/lib/redmine/config/configuration.yml
$ vi /var/lib/redmine/config/configuration.yml
$ diff /var/lib/redmine/config/configuration.yml.example /var/lib/redmine/config/configuration.yml

config/configuration.yml

15a16
>     delivery_method: :sendmail

RedmineのWebUIでアップロードされたファイルの保存先ディレクトリを作成します。

ファイルの保存先を変更するには、config/configuration.ymlの「attachments_storage_path」に目的のパスを指定します。

$ logout
# mkdir -p /var/redmine/files
# chown app-user:app-user /var/redmine/files
# su - app-user

gemインストール

Redmineが使用するgemをインストールします。

$ cd /var/lib/redmine
$ bundle install --without development test rmagick
$ bundle exec rake generate_secret_token

データベース更新

$ cd /var/lib/redmine
$ bundle exec rake db:migrate RAILS_ENV=production

クリーンアップ

$ bundle exec rake tmp:cache:clear tmp:sessions:clear RAILS_ENV=production

Unicornインストール

Gemfile.local 作成

$ cd /var/lib/redmine
$ cat << EOF > Gemfile.local
gem "unicorn"
EOF

依存パッケージインストール

$ bundle install --without development test

アプリケーションサーバー動作確認と初期設定

$ bundle exec unicorn_rails -l 3000 -E production

http://host-address:3000/ などでアクセスして、RedmineのWebUIが表示できることを確認します。(終了するには「Ctrl + C」を入力します) ここで、管理者アカウントのパスワードを変更しておきます。管理者アカウントのIDと初期パスワードはともに「admin」です。

デーモンプロセス化

systemctlコマンドでアプリケーションサーバーを起動・停止できるようにします。今回、アプリケーションサーバーは3000番ポートでリッスンすることとします。

アプリケーション設定

$ vi /var/lib/redmine/config/unicorn.rb

/var/lib/redmine/config/unicorn.rb

worker_processes 2

app_path = "/var/lib/redmine"

listen 3000
#listen  File.expand_path('tmp/unicorn.sock', app_path)
pid File.expand_path('tmp/unicorn.pid', app_path)
stderr_path File.expand_path('log/unicorn.stderr.log', app_path)
stdout_path File.expand_path('log/unicorn.stdout.log', app_path)

preload_app true

timeout 30

if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

SECRET_KEY_BASE 取得

SECRET_KEY_BASEの値は、次のコマンドを実行して取得できます。

$ cd /var/lib/redmine
$ bundle exec rake secret

ここで 0~9、a~f 128文字からなる文字列を得られます。

systemctlコマンド用スクリプト作成

systemctlコマンドで指定するサービス名でファイルを作成します。サービス起動順序の依存関係として、MariaDBが起動してからアプリケーションサーバーを起動するよう指定します。

$ logout
# vi /etc/systemd/system/unicorn-redmine.service

/etc/systemd/system/unicorn-redmine.service

[Unit]
Description=redmine
Wants=mariadb.service
After=mariadb.service

[Service]
User=app-user
WorkingDirectory=/var/lib/redmine
Environment=RAILS_ENV=production
Environment=RAILS_SERVE_STATIC_FILES=1
Environment=SECRET_KEY_BASE=<[0-9a-f]{128}な文字列>
SyslogIdentifier=unicorn-redmine
PIDFile=/var/lib/redmine/tmp/unicorn.pid
ExecStart=/home/app-user/.rbenv/shims/bundle exec "unicorn_rails -D -c /var/lib/redmine/config/unicorn.rb -E production"

[Install]
WantedBy=multi-user.target

アプリケーションサーバー起動

# systemctl start unicorn-redmine
# systemctl status unicorn-redmine
# systemctl enable unicorn-redmine

もしここでサービスの起動が失敗する場合は、/var/lib/redmine/log/unicorn.stderr.log を確認してください。 私の環境で起こった事なのですが、「アプリケーションサーバー動作確認と初期設定」で手動では起動できるけれど、systemctl start unicorn-redmine を実行すると失敗する、という現象が発生しました。原因は /var/lib/redmine/tmp/unicorn.sock がソケットファイルではなく通常ファイルになってしまっていたことでした。/var/lib/redmine/tmp/unicorn.sock を削除して、再度 systemctl start unicorn-redmine を実行すれば、無事起動するようになりました。エラーメッセージは下記のとおりです。

F, [2017-10-22T14:02:23.476984 #1554] FATAL -- : error adding listener addr=/var/lib/redmine/tmp/unicorn.sock
/home/app-user/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/unicorn-5.3.0/lib/unicorn/socket_helper.rb:131:in `bind_listen': socket=/var/lib/redmine/tmp/unicorn.sock specified but it is not a socket! (ArgumentError)

nginxインストール

Redmineがアプリケーションサーバーとして起動しました。これのフロントエンドとしてNginxをインストールして、連携させます。

リポジトリ追加

# yum install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

パッケージインストール

# yum install nginx

アプリケーションサーバーとの連携

# mv /etc/nginx/conf.d/default.conf /root/originalfiles/etc__nginx__conf.d__default.conf
# vi /etc/nginx/conf.d/redmine.conf
upstream redmine {
    server  localhost:3000;
}

server {
    listen  80;
    server_name  redmine.example.com;
    root  /var/lib/redmine/public;

    proxy_connect_timeout  60;
    proxy_read_timeout  60;
    proxy_send_timeout  60;

    location / {
        if (-f $request_filename) {
          break;
        }

        proxy_pass  http://redmine;
        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;
    }
}
# systemctl restart nginx
# systemctl status nginx
# systemctl enable nginx

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください