[ Redmine index ]

CentOS 6上でRedmine 2を動かすメモ

このページの内容はRedmine 2.2.2、Ruby 1.9.3での記述となっており、少々古くなっています。
CentOS 6とRedmine 2の最新セットアップ情報は、こちらのページに記載しています。

目次

はじめに

Redmineとは

Redmineは、チケット管理システムとしての機能に、Wiki、掲示板、ファイル管理などの情報共有機能を加え、バージョン管理システムとの連携機能を持たせたツールです。ソフトウェア開発プロジェクトだけでなく、チケット管理の仕組みに様々な業務を載せて管理することができる、ある種のITシステムに活用することができます。

Redmineの構成と今回構築する構成要素の組み合わせ

Redmineは、Ruby on Railsと呼ぶWebアプリケーション構築の土台となるフレームワーク上に作られています。名前のとおりRuby言語で書かれています。次にRedmineが動作するソフトウェア構成の概略図を示します。

Redmineトップレベル構成図
Redmine    HTTP
サーバー  
Ruby on Rails   連携
(Railsアプリケーションサーバー)
Ruby  RDBMS 
OS   

 
 OSは、CentOS 6(執筆時点では6.3が最新)を使用します。
 Rubyは、1.8.7か1.9.3が必要となります。
 RDBMSは、MySQL, PostgreSQL, SQLiteが利用可能です。
 Ruby on Rails は、Redmineバージョンによって指定され、Redmie 2.2.2では、Rails 3.2.11を使用します。
 Redmineは2.2.2(執筆時点の最新)を使用します。
 HTTPサーバーは、Apache 2、NGiNX、WEBrickなどが利用可能で、連携(Railsアプリケーションサーバー)はHTTPサーバーの選択にもよりますが、Mongrel、Passenger、Thin、Unicornなどが利用可能です。

 今回インストールする組み合わせは次とします。

構成要素  使用する製品 バージョン  備考 
OS CentOS 6.3  x86_64(64bit版) 
Ruby Ruby 1.9.3  CentOS 6の標準搭載Rubyは1.8.7のため、別途ソースからビルドして使用 
RDBMS MySQL 5.1.66  CentOS 6の標準搭載品 
Ruby on Rails Ruby on Rails  3.2.11   
Redmine  Redmine  2.2.2  
HTTPサーバー連携  Passenger  3.0.18   
HTTPサーバー  Apache  2.2.15  CentOS 6の標準搭載品 

なお、HTTPサーバー連携にUnicorn、HTTPサーバーにNginxを使う設定を追記しました。

構成要素の選択について補足メモ

Ruby

CentOS 6において、Rubyの主な選択肢は次の3つです。

  1. CentOS 6標準搭載のRuby 1.8.7を使用する
  2. Ruby Enterprise Edition 1.8.7 をダウンロードしビルドして使用する
  3. Ruby 1.9.3をダウンロードしビルドして使用する

Redmine 2が土台としているRuby on Rails 3.2は、Ruby 1.8.7で動作保証しているので、CentOS 6標準搭載品のRubyでもRedmineは動きます。

しかし、Ruby 1.8.7は製品サポート期間が終了間際であること(Rubyのアナウンスページ)、メモリ使用量などの性能が1.9.3あるいはRuby Enterprise Edition 1.8.7に比べ劣っていることがあります。
Ruby Enterprise Editionは開発を停止してメンテナンスモードに入っており(InfoQの記事「Ruby Enterpriseエディションが終わる。Phusionは、Passengerに注力」)、本記事では1.9.3を選択しました。

RDBMS

業務での運用(多人数でのアクセス)を考えると、SQLiteは候補から外れ、MySQLかPostgreSQLの選択となります。今回は、セットアップ経験があるMySQLを選択しました。

HTTPサーバー連携(Railsアプリケーションサーバー)

参考文献の比較資料も見ながら、Passengerを選択しました。(なお、Unicornを追記しています)

HTTPサーバー

デファクトといっていいApacheを使います。(なお、Nginxを追記しています)

OS(計算機)のメモリ

経験的に、物理メモリ3GBを搭載したマシンでの運用が安定しています。1GB〜2GBの物理メモリでは、メモリ不足によるスラッシングが発生し、Redmineの動作が著しく遅くなることがあります。

インストール方針

インストールにあたって考慮事項を記述します。

SELinux対応 

CentOSはエンタープライズ環境での使用向けにデフォルトでSELinuxが有効(Targeted)です。しかし、Redmineを動かすにはSELinuxの設定が少なからず必要です。一番の困難はPassengerと思います。また、rubyをソースからビルドし/usr/local以下に入れる場合、SELinuxが関知しなさそうなディレクトリなので困る要因になります。

今回、SELinuxを有効にしたままRedmineを動かす手段を可能な限り追究してみたいと思いますが、現時点では達成できていません。SELinux有効の下、Passengerを動かすための設定追究の模様を次のページに記載しています。

非インターネット接続環境でのインストール

エンタープライズ環境といっても常にインターネットに接続可能というわけではありません。時には、インターネットとは接続不可能なクローズなネットワーク環境で動かしたこともあります。そこで、非インターネット接続環境でのインストールも実現できる手順を模索してみます。

しかし、bundlerによるgemパッケージインストールがRedmine 1.4から導入され、2.0ではgemパッケージが大幅に増えているようです。以前は依存関係を調べて必要なgemパッケージを列挙していましたが、2.0では60個くらいのgemを必要としているようなので、非インターネット環境のインストールは難易度が高くなっています。

インストール

セキュリティ設定の変更

SELinuxの設定をpermissiveに変更

/etc/selinux/config を修正します。

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

下線部がデフォルトのenforcingから修正した箇所です。

再起動で反映されます。

一時的な変更

setenforceコマンドで一時的に変更することができます。現在の設定はgetenforceで確認できます。

iptables(ファイアウォール)の設定にポート80を追加

デフォルトではポート80がファイアウォールでふさがれているため、許可を追加します。

現状の設定を確認

CentOSのデフォルトの設定内容を一覧します。

# iptables -L --line-number
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
5    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
#

外部からのパケットを受信するときのフィルターはINPUTに表示されます。

1. 接続状態がRELATEDまたはESTABLISHEDのパケットであれば通します。
2. ICMパケットは通します。
3. ローカルホストのパケットは通します。
4. 接続状態がNEW(新たな接続)のパケットはポート番号がsshのものだけ通します。
5. それ以外のパケットは拒否(REJECT)し、ICMPのエラーパケットを返します。

ここに、ポート番号がhttpのものを通す追加を行います。

TCPプロトコルにhttpポートの追加

コマンドでフィルターを追加します。

# iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport http -j ACCEPT
#

追加結果は次になります。

# iptables -L --line-number
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
5    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
6    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
... (以下略)

結果を保存します。

# service iptables save
補足

フィルターの削除は、

# iptables -D INPUT 5

CentOSパッケージの追加インストール

インストール作業にて必要となるCentOSパッケージがインストールされていなければ、最初にインストールしておきます。なお、CentOS標準パッケージ以外に、EPELリポジトリにあるパッケージも必要となります。

yumリポジトリ設定にEPELを追加

今まで手でyumリポジトリ設定ファイルを編集してましたが、Redmine.jpの手順を見ると、EPELリポジトリ設定用のrpmパッケージをインストールするだけでよいことを知りました。

64bit版なので、以下URLをブラウザで開き、Packages項に記載のリンクをrpmでインストールします。

コマンド実行例は以下です。

# rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

rpm -ql epel-release でインストールされたファイル一覧が分かります。

yumで追加インストール

# yum groupinstall "Development Tools"
  :
# yum install openssl-devel readline-devel zlib-devel curl-devel libyaml-devel
  :
# yum install mysql-server mysql-devel
  :
# yum install httpd httpd-devel
  :
# yum install ImageMagick ImageMagick-devel
  :
#

ちなみにEPELリポジトリからインストールされたパッケージは以下です。@epelとついているのがyumでEPELから入ったパッケージです。(installedは、yumではなくrpmコマンドで入れた場合のようです)

# yum list installed | grep epel
epel-release.noarch   6-7               installed
libyaml.x86_64        0.1.3-1.el6       @epel
libyaml-devel.x86_64  0.1.3-1.el6       @epel

非インターネット接続環境へのインストール・メモ

標準パッケージについては、CentOS 6のメディアからインストール可能です。メディアをDVDにセットしてyumコマンドを実行します。

EPELからインストールするlibyamlとlibyaml-develの2つについては、別途rpmファイルをダウンロードしておき、yum localinstallコマンドでインストールします。

Ruby 1.9.3のインストール

CentOS 6は標準でruby 1.8.7なので、別途1.9.3をインストールします。インストールには大まかに次の方法があります。

個人用のマシンならソースからビルドして入れてもよいですが(いわゆる野良ビルド)、運用管理をしっかりする場合、いくつかのサーバーにRedmineを構築する場合はRPMパッケージ化した方がよいでしょう。

Rubyのソースをビルドおよびインストール(野良ビルド)

より1.9.3の最新パッチレベル版を入手します。

$ tar xjf ruby-1.9.3-p327.tar.bz2
$ cd ruby-1.9.3-p327
$ ./configure
    :
$ make
    :
$ su
    :
# make install
    :

/usr/localの下にインストールされます。

インストール後、動作確認をします。

# ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
# which ruby
/usr/local/bin/ruby
#

RPMパッケージの作成とインストール

CentOS 6.2でRuby 1.9.3をRPM化するブログがありました。

ここを見ながら、わりと簡単にruby 1.9.3のRPM化ができました。おおよその手順は次になります。

RPMパッケージを作成する環境、コマンド等については、「RPMパッケージを作成するためのメモ書き」ページを参照ください。

実行メモ

~$ cp ruby193.spec ~/rpm/SPECS
~$ vi rpm/SPECS/ruby193.spec
...
~$ cp ruby-1.9.3-p362.tar.bz2 rpm/SOURCES/
~$ rpmbuild -ba rpm/SPECS/ruby193.spec
...
~$ ls rpm/RPMS/x86_64/ruby*
rpm/RPMS/x86_64/ruby-1.9.3p362-1.el6.x86_64.rpm
rpm/RPMS/x86_64/ruby-debuginfo-1.9.3p362-1.el6.x86_64.rpm
~$

ruby193.specの修正箇所のメモ

-%define rubyminorver    p0
+%define rubyminorver    p362

-Release:        2%{?dist}
+Release:        1%{?dist}

-Source0:        ftp://ftp.ruby-lang.org/pub/ruby/ruby-%{rubyver}-%{rubyminorver}.tar.gz
+Source0:        ftp://ftp.ruby-lang.org/pub/ruby/ruby-%{rubyver}-%{rubyminorver}.tar.bz2

 %changelog
+* Mon Jan 14 2013 Toru Takahashi <torutk@gmmail.com> - 1.9.3-p362
+- Update ruby version to 1.9.3-p362

MySQLの設定

MySQLで日本語を使用するために、文字集合の定義を設定ファイルに記述します。

次に、Redmine用のデータベース(領域)およびMySQLのユーザー登録をします。

文字集合の設定

/etc/my.cnf に追記します。

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
character-set-server=utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysql]
default-character-set=utf8

上記で下線を引いた箇所が追記部分です。

ストレージエンジンの設定

MySQLはストレージエンジンにMyISAMとInnoDBが選択できます。CentOS 6のMySQL 5.1はデフォルトでMyISAMなので、InnoDBを使う場合は設定に以下を追記します。

[mysqld]
  :
default-storage-engine=InnoDB

RedmineはDBとしては更新作業が多いので、InnoDBが向いているのではないかと思われます。

パフォーマンスパラメータ設定

InnoDBを使う場合、デフォルトの設定値ではおそらく小さいので、メモリ容量に応じて大きめの値を指定するとよいです。

以下は、128MBをMySQLに割り当てる場合

[mysqld]
  :
innodb_buffer_pool_size = 64M       ・・・・・・ (1)
innodb_additional_mem_pool_size = 2M    ・・・・・・ (2)
innodb_log_file_size = 16M         ・・・・・・ (3)
innodb_log_buffer_size = 8M        ・・・・・・ (4)
(1) innodb_buffer_pool_size
InnoDBのデータ・インデックスなどをキャッシュする領域。MySQLに割り当てられるメモリの半分を目安に指定します。(デフォルト8M)
(2) innodb_additional_mem_pool_size
InnoDBのテーブル定義などの格納。テーブル数が多いときは増やすとよい値。(デフォルト1M)
(3) innodb_log_file_size
InnoDBへの書き込みはまずログファイルに書き込まれ、その後テーブルスペースに反映される。大きめの値がよい。(デフォルト5M)
(4) innodb_log_buffer_size
InnoDBへの書き込みを更新ログとしてメモリに保持するサイズ。8M〜64MB程度か?(デフォルト1M)

innodb pluginの使用

InnoDBを選択する場合、MySQL 5.1標準のInnoDBエンジンの他に、性能改善型InnoDBプラグインが標準で利用可能です。これは、CPU、メモリ、I/Oのすべてにおいて性能改善されたもので、MySQL 5.5ではこのInnoDBプラグインがInnoDBエンジンになっています。

InnoDBプラグインを使う場合は設定に以下を追記します。(plugin-loadで始まる4行は折り返ししているが実際は継続行)

[mysqld]
  :
ignore-builtin-innodb
plugin-load=innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_loc
ks=ha_innodb_plugin.so;innodb_cmp=ha_innodb_plugin.so;innodb_cmp_reset=ha_innodb
_plugin.so;innodb_cmpmem=ha_innodb_plugin.so;innodb_cmpmem_reset=ha_innodb_plugi
n.so
MySQLの起動に失敗した場合

MySQLの初回起動時に、innodb pluginを使用する設定を記述した場合に、次のように起動エラーとなりました。

# service mysqld start
MySQL Daemon failed to start.
mysqld を起動中:  [失敗]
#

ログファイル(/var/log/mysqld.log)を見るとエラーが記録されています。

/usr/libexec/mysqld: Table 'mysql.plugin' doesn't exist
121201 22:11:12 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgr
ade to create it.
  :(中略)
121201 22:11:13 [ERROR] Fatal error: Can't open and lock privilege tables: Table
 'mysql.host' doesn't exist

ぐぐると、対処としてデータベースの初期化をするという記述をいくつか見かけました。

# mysql_install_db
Installing MySQL system tables...
OK
Filling help tables...
OK

再度MySQLを起動します。

# service mysqld start
mysqld を起動中:  [  OK  ]
#

MySQLユーザー登録

Redmine用のデータベースを作成し、ユーザー登録をします。なお、この作業にはmysqlサービスが稼働している必要があります。

MySQLサービスの起動
# service mysqld start
  :
#

MySQLをマシン起動時に自動で立ち上げるよう設定をしておきます。

# chkconfig --list mysqld
mysqld          0:off   1:off   2:off   3:off   4:off   5:off   6:off
# chkconfig mysqld on
# chkconfig --list mysqld
mysqld          0:off   1:off   2:on    3:on    4:on    5:on    6:off
#
Redmine用データベース作成
# mysql -uroot
  :
mysql> CREATE DATABASE redmine DEFAULT CHARACTER SET utf8;
Query OK, 1 row affected (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| redmine            |
| test               |
+--------------------+
4 rows in set (0.00 sec)

mysql>

下線部(redmine)がデータベース名の指定です。データベース名はRedmineの設定ファイル(database.yml)で指定するので、好みで変更しても大丈夫です。

ユーザー登録
mysql> GRANT ALL ON redmine.* TO redmine@'localhost' IDENTIFIED BY 'foobar';
  :
mysql> FLUSH PRIVILEGES;
  :
mysql>

Redmine用データベースに作成した各テーブルに対し、すべての権限(ALL)を持つユーザを作成します。最初の下線部(redmine)がユーザー名、2番目の下線部(foobar)がパスワードです。データベース接続ユーザー名/パスワードはRedmineの設定ファイル(database.yml)で指定するので、好みで変更しても大丈夫です。

なお、@'localhost'の指定をしない場合、ネットワーク越しのアクセスはOKですが同一マシンからMySQLへのアクセスがエラーとなります。Redmineの場合、同一マシンからのアクセスとなるので、'localhost'の指定が必要です。

Redmine(本体)のインストール

ソース一式の入手と展開

Redmineのインストール場所は、本家インストールガイドにしたがって/var/lib/redmine-バージョン番号 とし、/var/lib/redmine をシンボリックリンクとして作成します。本記事では実体のインストールディレクトリを以降<Redmineインストールディレクトリ>と表現します。

# cd /var/lib
# tar xzf /tmp/redmine-2.2.2.tar.gz
# ln -s redmine-2.2.2 redmine
# ls -l
  :
lrwxrwxrwx   1 root    root      13  1月 26 22:44 2013 redmine -> redmine-2.2.2
drwxrwxr-x  16 1000    1000    4096  1月 21 05:05 2013 redmine-2.2.2
  :
#

データベース接続設定

<Redmineインストールディレクトリ>/config/database.ymlを作成します。

production:
  adapter: mysql2
  database: redmine
  host: localhost
  username: redmine
  password: foobar
  encoding: utf8  

下線部は、MySQLの設定で使用した名前に合わせます。

Ruby 1.8.7の場合

adapterの記述は、mysqlとします。mysql2はRuby 1.9以降用です。

メール送信設定

<Redmineインストールディレクトリ>/config/configuration.ymlを作成します。

メール送信の設定は、環境によってさまざまななので、具体的な設定はドキュメントをあたってください。
以下は認証不要のSMPTサーバーの場合です。

production:
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: "localhost"
      port: 25
      domain: 'example.com'

最初の下線部(address行)には、SMTPサーバーのアドレスを記述します。
2番目の下線部(domain行)には、Redmineマシンのドメイン名を記述します。

Redmineが使用するgemパッケージのインストール

bundlerを使って、RedmineおよびRuby on Railsが依存するgemパッケージをインストールします。

依存するgemパッケージは、Redmineを展開した中のGemfileに記述されています。

gemパッケージをインストールする前に、初期状態でgemでインストールされている一覧を確認しておきます。

# gem list

*** LOCAL GEMS ***

bigdecimal (1.1.0)
io-console (0.3)
json (1.5.4)
minitest (2.5.1)
rake (0.9.2.2)
rdoc (3.9.4)
#

bundlerのインストール

まず、bundlerをインストールします。

# gem install bundler --no-rdoc --no-ri
Fetching: bundler-1.2.3.gem (100%)
Successfully installed bundler-1.2.3
1 gem installed
#

Redmineが使用するgemパッケージのインストール

gemパッケージは、システム共通の場所にインストールするか、Railsアプリケーション(今回はRedmine)固有の場所にインストールするかを指定できます。同一マシンで異なるバージョンのRailsアプリケーションを動かすときは後者でないと競合が生じます。

そこで、今回はRedmine固有の場所にインストールすることにします。

bundleコマンドは、カレントディレクトリにあるGemfileを読むので、実行時はredmineにカレントディレクトリを移動します。

# cd /var/lib/redmine
# bundle install --path vendor/bundler --without development test postgresql sqlite
Fetching gem metadata from http://rubygems.org/.........
Fetching gem metadata from http://rubygems.org/..
Installing rake (10.0.3)
Installing i18n (0.6.1)
Installing multi_json (1.5.0)
Installing activesupport (3.2.11)
Installing builder (3.0.0)
Installing activemodel (3.2.11)
Installing erubis (2.7.0)
Installing journey (1.0.4)
Installing rack (1.4.4)
Installing rack-cache (1.2)
Installing rack-test (0.6.2)
Installing hike (1.2.1)
Installing tilt (1.3.3)
Installing sprockets (2.2.2)
Installing actionpack (3.2.11)
Installing mime-types (1.19)
Installing polyglot (0.3.3)
Installing treetop (1.4.12)
Installing mail (2.4.4)
Installing actionmailer (3.2.11)
Installing arel (3.0.2)
Installing tzinfo (0.3.35)
Installing activerecord (3.2.11)
Installing activeresource (3.2.11)
Using bundler (1.2.3)
Installing coderay (1.0.8)
Installing rack-ssl (1.3.2)
Installing json (1.7.6) with native extensions
Installing rdoc (3.12)
Installing thor (0.17.0)
Installing railties (3.2.11)
Installing jquery-rails (2.0.3)
Installing mysql2 (0.3.11) with native extensions
Installing net-ldap (0.3.1)
Installing ruby-openid (2.1.8)
Installing rack-openid (1.3.1)
Installing rails (3.2.11)
Installing rmagick (2.13.1) with native extensions
Your bundle is complete! It was installed into ./vendor/bundler
Post-install message from rdoc:
Depending on your version of ruby, you may need to install ruby rdoc/ri data:

<= 1.8.6 : unsupported
 = 1.8.7 : gem install rdoc-data; rdoc-data --install
 = 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!

#

install した結果は、<Redmineインストールディレクトリ>/vendor/bundler以下に格納されます。

また、インストールで使用したgemパッケージファイル(*.gem)は、<Redmineインストールディレクトリ>/vendor/bundler/ruby/1.9.1/cache/ディレクトリに保存されます。

非インターネット接続環境へのインストール・メモ

bundler

あらかじめインターネット接続マシン上で、以下を実行します。

$ gem fetch bundler

gemファイルがダウンロードされるので、ターゲットマシンにコピーし、インストールします。

# gem intall bundler --local

--localオプションを指定すると、カレントディレクトリにあるgemファイルを対象にインストールします。

bundle install でインストールするもの

bundleコマンドは、ローカルに置かれたgemファイル群からインストールすることができます。

あらかじめインターネット接続マシン上で、上述の手順でbundle installを実行したときに保存されたgemファイル(<Redmineインストールディレクトリ>/vendor/bundler/ruby/1.9.1/cache/ディレクトリの中)を、ターゲットマシンの<Redmineインストールディレクトリ>/vendor/cache/ディレクトリにコピーします。

Gemfileから、今回のインストールに不要なgem文を削除します。--withoutでインストールしないグループを指定しても、依存関係の判定は実行されてしまい、gemが存在しないとエラーとなるためです。

また、次のケースもruby 1.9.3ではインストール不要なgemですが、依存関係の判定ではcacheにgemが存在しないとエラーになってしまいます。これも削除しておきます。

gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]

--localオプションを追加してbundle install を実行します。

# bundle install --path vendor/bundler --without development test postgresql sqlite
 --local

bundleのインストール先確認

bundle show で指定したgemのインストール先が確認できます。

# bundle show tilt
/usr/lib64/ruby/gems/1.9.1/gems/tilt-1.3.3

上記は、--path指定なしにbundle installした場合の例です。

Redmineの初期化

セッションデータ暗号化の鍵生成

# cd /var/lib/redmine-2.2.2
# bundle exec rake generate_secret_token
#

bundlerでインストールしたgemのコマンドは、bundle execで実行します。

データベースを初期構築

# bundle exec rake db:migrate RAILS_ENV=production
==  Setup: migrating ==========================================================
-- create_table("attachments", {:force=>true})
  :
==  PopulateEnumerationsPositionName: migrated (0.0032s) ======================

#

動作確認

WEBrickを実行し、Redmineが正常に起動するかを確認します。

ちなみにSELinuxは有効(Enforcing)のままです。

WEBrick起動
# ruby script/rails server webrick -e production
=> Booting WEBrick
=> Rails 3.2.11 application starting in production on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
  :
[2013-01-26 23:27:47] INFO  WEBrick::HTTPServer#start: pid=16590 port=3000
同一マシン上のブラウザからアクセスし確認

http://localhost:3000 に接続し、Redmine画面が表示されたら正常です。

違うマシンからの確認は、障害原因の候補が増えるので、失敗したときの切り分けが困難になります。

ファイアウォールの一時停止

ファイアウォール(iptablesサービス)が動作していると、ポート3000はブロックされています。そのときは確認にあたって一時停止します。

# service iptables stop
iptables: ファイアウォールルールを消去中:                  [  OK  ]
iptables: チェインをポリシー ACCEPT へ設定中filter         [  OK  ]
iptables: モジュールを取り外し中:                          [  OK  ]
#

Passengerのインストール

Passengerはgemパッケージで提供されていますが、RedmineのGemfileには記載されていないので、bundleではインストールされません。そこで、bundleでインストールできるよう追加の設定をします。

<Redmineインストールディレクトリ>/Gemfile.local を新規に作成し以下を記述

gem "passenger"

インストール

<Redmineインストールディレクトリ>で、bundle updateを実行します。

# bundle update
  :
Installing daemon_controller (1.1.0)
Installing fastthread (1.0.7) with native extensions
  :
Installing passenger (3.0.18)
  :
# 

--path 指定を今回は省略することができます。bundleを実行したときのオプションが、<Redmineインストールディレクトリ>/bundle/configファイルに保存されるためです。

Apache2に組み込むライブラリをビルドします。

# bundle exec passenger-install-apache2-module
Welcome to the Phusion Passenger Apache 2 module installer, v3.0.18.
  :
Press Enter to continue, or Ctrl-C to abort.

gemをふつうにインストールしていると、PATHの通った場所にpassenger-install-apache2-moduleが置かれますが、今回はbundleでしかもRailsアプリケーション固有の場所にgemをインストールしているので、PATHが通っていません。そこで、bundleで--path指定でインストールしたコマンドを実行するためのユーティリティ bundle exec を使います。

Enterキーを押すとビルドが開始されます。しばらくすると、

The Apache 2 module was successfully installed.

Please edit your Apache configuration file, and add these lines:

   LoadModule passenger_module /var/lib/redmine-2.2.2/vendor/bundler/ruby/1.9.1/gems/passenger-3.0.18/ext/apache2/mod_passenger.so
   PassengerRoot /var/lib/redmine-2.2.2/vendor/bundler/ruby/1.9.1/gems/passenger-3.0.18
   PassengerRuby /usr/bin/ruby

After you restart Apache, you are ready to deploy any number of Ruby on Rails
applications on Apache, without any further Ruby on Rails-specific
configuration!

Press ENTER to continue.

と出るのでEnterキーを押します。

--------------------------------------------
Deploying a Ruby on Rails application: an example

Suppose you have a Rails application in /somewhere. Add a virtual host to your
Apache configuration file and set its DocumentRoot to /somewhere/public:

   <VirtualHost *:80>
      ServerName www.yourhost.com
      # !!! Be sure to point DocumentRoot to 'public'!
      DocumentRoot /somewhere/public
      <Directory /somewhere/public>
         # This relaxes Apache security settings.
         AllowOverride all
         # MultiViews must be turned off.
         Options -MultiViews
      </Directory>
   </VirtualHost>

And that's it! You may also want to check the Users Guide for security and
optimization tips, troubleshooting and other useful information:

  /var/lib/redmine-2.2.2/vendor/bundler/ruby/1.9.1/gems/passenger-3.0.18/doc/Use
rs guide Apache.html

Enjoy Phusion Passenger, a product of Phusion (www.phusion.nl) :-)
http://www.modrails.com/

Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
# 

ビルドが完了しました。

非インターネット接続でのインストール

インターネットに接続しない環境では、あらかじめpassengerとその依存gemファイルを入手し、<Redmineインストールディレクトリ>/vendor/cacheディレクトリにコピーしておき、--localオプションを追加します。

$ gem fetch passenger fastthread daemon_controller
$
# cp *.gem /var/lib/redmine/vendor/cache/
# cd /var/lib/redmine
# bundle update --local

Apache2 への組み込みはインターネット接続でのインストールと同一手順です。

Apacheの設定

/etc/httpd/conf.d/passenger.conf を新規作成して記述します。

# bundle exec passenger-install-apache2-module --snippet > /etc/httpd/conf.d/passenger.conf
# cat /etc/httpd/conf.d/passenger.conf
LoadModule passenger_module /var/lib/redmine-2.2.2/vendor/bundler/ruby/1.9.1/gem
s/passenger-3.0.18/ext/apache2/mod_passenger.so
PassengerRoot /var/lib/redmine-2.2.2/vendor/bundler/ruby/1.9.1/gems/passenger-3.
0.18
PassengerRuby /usr/bin/ruby
#

シンボリックリンクを /var/www/htmlに作成します。

# ln -s /var/lib/redmine/public /var/www/html/redmine
#

/etc/httpd/conf.d/passenger.conf にディレクトリを追記します。

RailsBaseURI /redmine

ApacheからRedmineをアクセスできるように所有者変更

# chown -R apache.apache /var/lib/redmine-2.2.2
# 

Apacheの起動

マシン起動時に自動起動するように設定し、確認のため手動でApacheサーバーを起動します。

# chkconfig httpd on
# service httpd start
  :
#

トラブルシュート

httpdが起動しない

SELinuxが有効の状態だとエラーとなります。

# chkconfig httpd on
# service httpd start
httpd を起動中: httpd: Syntax error on line 221 of /etc/httpd/conf/httpd.conf: S
yntax error on line 1 of /etc/httpd/conf.d/passenger.conf: Cannot load /var/lib/
redmine-2.2.2/vendor/bundler/ruby/1.9.1/gems/passenger-3.0.18/ext/apache2/mod_pa
ssenger.so into server: /var/lib/redmine-2.1.2/vendor/bundler/ruby/1.9.1/gems/pa
ssenger-3.0.18/ext/apache2/mod_passenger.so: failed to map segment from shared o
bject: Permission denied
                                                           [失敗]
#

一時的にSELinuxを無効にして動作確認します。

# setenforce 0
# getenforce
Permissive
# service httpd start
httpd を起動中: httpd: apr_sockaddr_info_get() failed for defghi
httpd: Could not reliably determine the server's fully qualified domain name, us
ing 127.0.0.1 for ServerName
                                                           [  OK  ]
#

永続的にSELinuxを無効化する手順は本ページ上述のSELinux設定を参照ください。

試み1

<Redmineインストールディレクトリ> 以下のファイルに、httpd_sys_content_t を付与してみました。

# chcon -R -h -t httpd_sys_content_t /var/lib/redmine-2.2.2
#

すると、httpdは起動するようになったけれども、内部(Passengerの起動)でエラーになりました。

/var/log/http/error_logの抜粋

[ pid=20703 thr=140558060439328 file=ext/common/Watchdog.cpp:1114 time=2012-05-2
5 01:51:12.535 ]: Cannot change the directory '/tmp/passenger.1.0.20701/generati
on-0/buffered_uploads' its UID to 48 and GID to 48: Operation not permitted (1)
     in 'void Passenger::ServerInstanceDir::Generation::create(bool, const std::
string&, const std::string&, uid_t, gid_t)' (ServerInstanceDir.h:76)

[Fri May 25 01:51:12 2012] [error] *** Passenger could not be initialized becaus
e of this error: Unable to start the Phusion Passenger watchdog: it seems to hav
e crashed during startup for an unknown reason, with exit code 1

SELinux有効で起動するようにする方法は、こちらのページに記載しています。

別マシンからアクセスできない

ファイアーウォールがポート80をふさいでると思われます。本ページ上述のiptablesの設定に沿ってポート80を許可します。

プラグインのインストール

共通事項

プラグイン・インストール・ディレクトリ

Redmine 2.0から、プラグインをインストールするディレクトリが、<Redmineインストールディレクトリ>/plugins になりました。

プラグインのディレクトリ名

入手するプラグインによっては、そのバージョン管理のチェンジセットハッシュが含まれるディレクトリ名だったりします。その場合、正しいディレクトリ名に変更する必要があります。正しいディレクトリ名の調べ方は、プラグインを展開した中にあるinit.rbファイルを開き、Redmine::Plugin.register 行を見ます。

例えば、Wiki Extensionsプラグインの場合、init.rbには次の記述があります。

Redmine::Plugin.register :redmine_wiki_extensions do

この場合、ディレクトリ名は redmine_wiki_extensionsが正しい名前となります。

プラグインのデータベース・マイグレーション

データベースにプラグイン固有のテーブルを使用する場合、マイグレーションを実行しテーブルを作成します。

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production

プラグインのアンインストール

# bundle exec rake redmine:plugins:migrate NAME=redmine_wiki_extensions \
 VERSION=0 RAILS_ENV=production

を実行します。NAME=のところにはプラグイン名(上述ディレクトリ名でinit.rbの中を調べたもの)を記述します。

次に、pluginsディレクトリからプラグインを削除します。

# rm -r plugins/redmine_wiki_extensions

プラグインが必要とするgemファイル(追記)

Redmineインストールディレクトリにおいて、bundle updateを実行すると、配下のpluginの中にあるGemfileも読み取って必要なものをインストールしてくれるようです。

プラグインのインストール時に、Gemfile.localに足さなくてもいいようです。

プラグイン利用の注意

プラグインはRedmine本体のバージョンアップに必ずしも速やかに追従するわけではありません。Redmine本体のバージョンアップ(=機能アップ)に早い段階で追従する場合、プラグインの対応がネックとなります。この場合、導入するプラグインは最低限に留め、Redmineバージョンアップに追従しているプラグインに絞った方がよいでしょう。

おススメプラグイン(プラグイン情報)

Wikiの機能を積極活用するならば、まっさきに入れておきたいプラグインがWiki Extensionsです。

ソースコード管理しているプロジェクトであれば、Code Reviewプラグインが重宝します。コードレビューの必需品です。

工数(作業時間)を収集/管理しているなら、Work Timeプラグインが便利です。表形式で各チケットの工数を同じ画面から入力できます。

イテレーション開発/リリースするなら、Parking lot chartプラグインが嬉しいです。

Wiki Extensions

RedmineのWiki機能を大幅に拡張するプラグインです。脚注、コメント追加、他のプロジェクト/wikiページへのリンク、ページ更新情報、ページへのタグ/タグクラウド、最近更新されたページ一覧、アクセスカウンタ、投票などのマクロの追加。プロジェクトのスタイルシート定義(Wiki以外にも適用)、フッター定義、オートプレビュー、任意のWikiページをプロジェクトメニュータブに追加、任意のWebページをwikiページ内に表示、テーブルのソート、など。

Redmine 2.2対応のプラグインは、0.6.1以降となります(0.6.0はRedmine 2.2.0では挙動がバギー)。
Redmine 2.1対応のプラグインは、0.6.0以降となります。
0.5.0はRedmine 2.0対応となります。0.4.xはRedmine 1.4対応となります。0.3.xはRedmine 1.3対応となります。

<Redmineインストールディレクトリ>/plugins に解凍・展開します。

# cd plugins
# unzip /tmp/redmine_wiki_extensions-0.6.1.zip
# 

ディレクトリ名:redmine_wiki_extensions

バンドル更新

# bundle update
# 

マイグレーション実行

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
# 

設定

Wikiへのコメント追加/編集/削除の権限を必要なロールに追加します。

問題解決ー不足するgemファイル

bundle updateを実行しないでmigrateを実行すると、次のようなエラーになります。

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
Could not find gem 'factory_girl_rails (>= 0) ruby' in the gems
 available on this machine.
Run `bundle install` to install missing gems.
#

プラグイン展開ディレクトリ(redmine_wiki_extensions)を見ると、Gemfileが存在しています。

source :rubygems

group :test do
  gem "simplecov"
  gem "simplecov-rcov"
  gem 'factory_girl_rails'

bundle updateを実行すると、最初にbundle installを実行したときのオプション--without testが効いて、チェックのみでこれらのgemをインストールすることなく更新済みにします。

しかし、bundle updateを実行せずにmigrateを実行した場合、どうやらtest用に指定しているgemが、rakeコマンドで必要とみなされているようです。

非インターネット接続環境では、bundle updateがうまくいかないので、redmine_wiki_extensions/Gemfileからgem文を削除します。

source :rubygems

group :test do
#  gem "simplecov"
#  gem "simplecov-rcov"
#  gem 'factory_girl_rails'
end

<Redmineインストールディレクトリ>に戻ってマイグレーションを実施します。

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
  :(中略)
Migrating redmine_wiki_preview_ext (Wiki preview extension plugin)...
#

Wiki Preview Extension

Wikiのプレビュー表示エリアを任意の位置に移動する機能、オートプレビュー機能(デフォルトは無効状態:他のプラグインの同等機能と干渉するため)を追加します。Wiki編集エリアの右隣に置くと、かなり便利です。

Redmine 2.1対応のプラグインは、0.2以降となります。なお、Ruby 1.9前提です。

# cd plugins
# unzip /tmp/redmine_wiki_preview_ext-RELEASE_0_2_0.zip
# 

ディレクトリ名:redmine_wiki_preview_ext

# mv mv redmine_wiki_preview_ext-RELEASE_0_2_0 redmine_wiki_preview_ext

Code Review

Redmine 2.1対応のプラグインは、0.6.0以降となります。
0.5.0はRedmine 2.0対応となります。0.4.xはRedmine 1.4対応となります。0.3.xはRedmine 1.3対応となります。

<Redmineインストールディレクトリ>/plugins に解凍・展開します。

# cd plugins
# unzip /tmp/redmine_code_review-0.6.1.zip
# 

ディレクトリ名:redmine_code_review

Code Reviewプラグインには、Gemへの依存がある(Gemfileが含まれる)ので、<Redmineインストールディレクトリ>で、bundleを更新します。

# cd ..
# bundle update
# 

プラグインのmigrateを実行します。

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production 

問題解決

redmine:plubins:migrate実行時にエラー

次のエラーが発生することがあります。

# bundle exec rake db:migrate_plugins RAILS_ENV=production
Could not find gem 'factory_girl_rails (>= 0) ruby' in the gems available on this machine.
Run `bundle install` to install missing gems.
#

bundle updateの実行を忘れた場合にこのエラーとなります。

インターネットに接続できない環境ならば、plugins/redmine_code_review/Gemfileを修正します。group :testのブロックは全削除。

Work Time

チケット1つ1つ開いて工数を入力せずに、表形式で各チケットの工数を同じ画面から入力できます。

Redmine 2.0対応のプラグインは、0.2.xとなります。これを、プラグインインストールディレクトリに展開します。
Redmine 2.1でも動作はしています。

# cd plugins
# unzip /tmp/redmine_work_time-0.2.6.zip
# 

ディレクトリ名:redmine_work_time

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production 

Assets

Redmine 2.0対応のプラグインは、0.0.3-12以降となります。上述URLの[Tags]には、古いバージョンしかリストされていないので、[Downloads]から最新版をダウンロードして、これを、プラグインインストールディレクトリに展開します。

Redmine 2.1でも動作はしています。

# cd plugins
# unzip /tmp/bshaffer-redmine-assets-plugin-RELEASE_0_0_3-12-g82d983a.zip
# 

ディレクトリ名:redmine_assets_plugin

# mv bshaffer-redmine-assets-plugin-82d983a redmine_assets_plugin
#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production

Absolute date

Redmine上で各種更新日付を、「〇〇日前」ではなく、「〇〇年〇月〇日前」のように絶対日付で表示します。
Redmine標準の更新日付「○○日前」の上をマウスオーバーすると、「2012/03/04 05:43:21」のようにツールチップ表示されるので、印刷(PDF)での閲覧が多い場合に導入を検討するとよさそうです。

※ 前という表記は消えないようです。

Redmine 2.0対応のプラグインは、2.0.0以降となります。これを、プラグインインストールディレクトリに展開します。

Redmine 2.1でも動作しています。

# cd plugins
# unzip /tmp/suer-redmine_absolute_dates-for-redmine-2.0-1-g7d2c8d3.zip
# 

ディレクトリ名:redmine_absolute_dates

# mv suer-redmine_absolute_dates-7d2c8d3 redmine_absolute_dates
#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production

Parking lot chart

バージョンの一覧と状態をタスクカード形式で列挙します。

最新版の0.0.7-4は、Redmine 2.0に対応しました。

Redmine 2.1でも動作しています。

# cd plugins
# unzip /tmp/daipresents-redmine_parking_lot_chart-0.0.7-4-gddbf0bf.zip
# 

ディレクトリ名:redmine_parking_lot_chart

# mv daipresents-redmine_parking_lot_chart-ddbf0bf redmine_parking_lot_chart
#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production

Backlogs

スクラム開発(アジャイル開発)でストーリーを管理します。

かなり複雑なプラグインで、いろいろ手をいれてくるので、もし入れるならBacklogs専用のRedmineを立てるべきか。

Redmine 2.1.2での動作実績はなさそうです。

# cd plugins
# unzip /tmp/unzip ~toru/backlogs-redmine_backlogs-v0.9.26-286-g777dbc7.zip
# 

ディレクトリ名:redmine_backlogs

# mv backlogs-redmine_backlogs-777dbc7 redmine_backlogs

インストール前に実行しておくこと

# bundle exec rake db:migrate RAILS_ENV=production
   :
# bundle exe rake tmp:cache:clear
# bundle exe rake tmp:sessions:clear

インストール

#  bundle exec rake redmine:backlogs:install RAILS_ENV=production
    :(中略)
Configuring story and task trackers...
-----------------------------------------------------
Which trackers do you want to use for your stories?
  1. バグ
  2. 機能
  3. サポート
  4. 移動
Separate values with a space (e.g. 1 3): 2
    :(中略)
done!
Installation complete. Please restart Redmine.
Thank you for trying out Redmine Backlogs!
# 

問題解決ーtest-unitのGemfile

#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production
You cannot specify the same gem twice with different version requirements. 
You specified: test-unit (>= 0) and test-unit (= 1.2.3)
#

とエラーになりました。Backlogsを展開したディレクトリにあるGemfileを見ると、次の記述があります。

group :test do
  (中略)
    gem "test-unit", "=1.2.3" if RUBY_VERSION >= "1.9"

Gemfileから、group :test 文全体を削除します。

問題解決ーthin がない

#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production
Could not find gem 'thin (>= 0) ruby' in the gems available on this machine.
Run `bundle install` to install missing gems.

とエラーになりました。プラグインのGemfileに記載のコメントを読むと、thinはテスト用に使用するgemファイルで、利用者側で問題の切り分けに使用するため、group :developmentではなく外側に記載しているとのことです。

そこで、選択肢として、thinを入れるか入れないかが考えられます。

thinを入れる場合

/var/lib/redmine-2.2.2/Gemfile.local に、gem "thin"を追記します。

gem "passenger"
gem "thin"

次に、libxml2-devel および libxslt-devel をインストールします。(thinが依存するnokogiriで利用)

# yum install libxml2-devel libxslt-devel
# bundle update

インターネット非接続のときは、次のgemが必要になります。

$ gem fetch holidays -v 1.0.3
$ gem fetch icalendar
$ gem fetch nokogiri
$ gem fetch open-uri-cached
$ gem fetch prawn
$ gem fetch daemons
$ gem fetch eventmachine
$ gem fetch ttfunk
$ gem fetch pdf-reader
$ gem fetch ruby-rc4
$ gem fetch Ascii85

これらを/var/lib/redmine/vendor/cacheの下にコピーします。

# bundle update
thinを入れない場合

プラグインのGemfileから、thinを削除します。

問題解決ーnokogiriのnative extension ビルドエラー

Backlogsプラグインを展開して、bundle updateを実行したときにエラーが発生しました。

# bundle update
Installing nokogiri (1.5.5) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby extconf.rb
checking for libxml/parser.h... no
-----
libxml2 is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
:(中略)
#

libxml2-develをインストールします。

# yum install libxml2-devel

bundle updateを実行、またエラー

Installing nokogiri (1.5.5) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby extconf.rb
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... no
-----
libxslt is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----

libxslt-develをインストールします。

# yum install libxslt-devel

Backlogsインストール後Redmineにアクセスすると出るメッセージ

Backlogsインストール後Redmineを起動すると、次のメッセージが表示されました。

バックログが設定されていません。設定画面 %{administration} > %{plugins}, からリンク %{configure} をクリックして設定してください。フィールドを設定後、このページへ戻りツールを利用してください。

BacklogsインストールしたRedmineのデータベースをバックアップし、Bakclogsを入れてないRedmineにインポートするとチケット作成時エラー

Backlogsプラグインが入ったRedmineのデータベースをバックアップし、新しいRedmine用にリストアして稼働させ、新しいチケットを作成したら内部エラーが発生しました。エラー箇所は、SQLのINSERT(issuesテーブルに対し、positionカラムのNOT NULL制約違反)でした。

backlogsがRedmine標準のテーブルissuesにカラムをいくつか追加しており、そのうちpositionカラムはNOT NULL制約を加えています

Backlogsプラグインは削除するときは、pluginsの下から削除する前に、データベースの変更を元に戻す操作を行う必要があります。しかし、今回はBacklogsプラグインがあるRedmineのデータをBacklogsプラグインのないRedmineへ移すので、ちょっと困ったことになりました。

XLS Export

チケットをExcel形式で出力します。オプションを選択すると、どの項目を出力するか選択できます。

Redmine 2.0対応は、v020以降です。(2012/6/27現在 v021)

Redmine 2.1でも動くようです。

Redmine 2.2以降で動かす場合、上記プラグインリリースをベースに修正を加えている次のフォークから入手するのがよいでしょう。

ディレクトリ名:ディレクトリ名は決め打ちではなく、実行時にディレクトリ名を取得するロジックとなっているようです。が、使用できる文字に制約があるので、バージョン番号等は削除しておくのがよさそうです。

# cd plugins
# unzip /tmp/redmine_xls_export_v021.zip
# 

必要なgemファイル、必要なプラグイン(後述)を先に入れてから、次の手順を実施します。

#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production
    :
#  bundle exec rake redmine:plugins:process_version_change RAILS_ENV=production
    :

必要なgemファイル

<Redmineインストールディレクトリ>/Gemfile.localに、以下を追記します。

gem "spreadsheet"

<Redmineインストールディレクトリ>で以下を実行します。

# bundle update

以下が追加インストールされました。

Installing nokogiri (1.5.5) with native extensions
Installing ruby-ole (1.2.11.4)
Installing spreadsheet (0.7.4)

必要なプラグイン

をインストールする必要があります。インストール手順は次のセクションに記述しています。

参考情報

Views with Revisions

XLS Exportプラグインに必要とされるプラグイン。

0.0.1は、Redmine 2.1に対応しています。

# cd plugins
# unzip /tmp/redmine_plugin_views_revisions_v001.zip
# 

ディレクトリ名:redmine_plugin_views_revisions

Issue Template

0.0.5は、Redmine 2.1に対応しています。

Bitbucketのissue_templateページで[Downloads]リンクを辿り、[Download]タブで、ダウンロードしたいファイルをクリックします。

ディレクトリ名:redmine_issue_templates

# cd plugins
# unzip /tmp/redmine_issue_templates-0.0.5.zip
# 

<Redmineインストールディレクトリ>で以下を実行します。

#  bundle exec rake redmine:plugins:migrate RAILS_ENV=production

使用にあたっての設定

IssueTemplateを利用するためには、ユーザーに権限が必要です。

使用方法メモ

issue_templateプラグインを有効にすると、新しいチケットに[チケットテンプレート]選択肢が追加されます。初期状態ではテンプレートが1つも登録されていないので、選択肢は[---]のみです。

テンプレートの登録は、権限のあるユーザーで、プロジェクトの[チケット]で右側メニューチケットテンプレートの[新規作成]をクリックします。

チケットテンプレート選択肢には、トラッカーが一致するテンプレートが候補として表示されます。

knowledgebase

階層的にカテゴリを設け、カテゴリに記事を追加していく一種のWiki。コメントを付ける、評価レートを付けるといった機能があります。

[Tags]をクリックし、最新バージョンをダウンロードします。

2.2.xバージョンは、Redmineの2.0.x、2.1.x、2.2.x、2.3.xに対応しています。

# cd plugins
# unzip /tmp/redmine_knowledgebase-2.2.0
# 

ディレクトリ名の変更

# mv redmine_knowledgebase-2.2.0 redmine_knowledgebase

データベース作成

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
  :
#

使用メモ

バージョン2.2では、Redmine全体で1つの知識DBを設ける仕様になっていますが、開発中の3.0ではプロジェクト毎に知識DBを持つように変わるようです(3.0.0のプレビューを試した限り)。

編集機能は、Wikiにある見出し毎の編集がないのがちょっと残念。

コメントが付けられるのはブログスタイルですね。Wiki Extensionsプラグインでもコメント、タグがあるのでちょっと微妙。

DMSF(Document Management System Features)

Redmineの標準文書モジュールを置きかえることを目的とし作成されたプラグイン。

ダウンロードは、[Branches]をクリックし、バージョン(devel-1.4.6)を選択し[ZIP]ボタンを押します。

Redmineの2.0.xに対応します(2.1系も?)。

ディレクトリ名:redmine_dmsf

# cd plugins
# unzip /tmp/redmine_dmsf-devel-1.4.6.zip
#

ディレクトリ名の変更

# mv redmine_dmsf-devel-1.4.6 redmine_dmsf

追加Gemのインストール

# bundle install --without development test postgresql sqlite xapian

データベース作成

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
  :
#

インストールトラブルメモ

Redmine Attach Screenshot

クリップボードにコピーされている画像をRedmineに貼るプラグイン。PrintScreenキーで画像をキャプチャした(クリップボードに画像がコピーされた)状態で、このプラグインを操作すると、画像がファイルとして添付され、インライン表示するマクロ文字列を生成する機能があります。画像はプラグインの機能で任意サイズの矩形で切り取ることができます。

リポジトリへのリンクをたどり、[Downloads]をクリック、[Tags]タブをクリックし、最新のバージョン番号の付いたタグの右端にあるzip等のリンクをクリックしてダウンロードします。

0.4.5は、Redmine 2.0.x、2.1.x、2.2.xに対応しています。

ディレクトリ名:redmine_inline_attach_screenshot

# cd plugins
# unzip /tmp/StrangeWill-redmine-inline-attach-screenshot-bd1959a41481.zip
#

ディレクトリ名の変更

# mv StrangeWill-redmine-inline-attach-screenshot-bd1959a41481 \
redmine_inline_attach_screenshot

このプラグインを利用するには、Webブラウザ側でJava Pluginが必要です。Java Pluginは、Java実行環境であるJRE(Java Runtime Environment)をインストールする際に、そのマシンにインストールされているブラウザのプラグインとして登録されます。

なお、ブラウザによってはデフォルトで無効状態になっていることがあるので、その際はJava Pluginを有効にします。

注記) Web系の技術はJava Pluginに限らずセキュリティ脆弱性に対するアップデートが頻繁に発生します。極力最新に更新をしておきます。アップデートに関する参考記事が@ITにあります。→ Java Runtime Environment (JRE)のバージョンを調べる

Clipboard Image Paste

クリップボードにコピーされている画像をRedmineに貼るプラグイン。先のRedmine Attach Screenshotと同じ機能ですが、チケット以外にWiki、ニュース、フォーラム、文書とで対応しています。また、JavaScriptで実装されているのでJava Pluginは不要です。

ただし、対応ブラウザがChromeかFilefoxとなります。

リポジトリへのリンクをたどり、[Tags]をクリックし、最新バージョンを入手します。

v1.4は、Redmine 2.2.xに対応しています。

ディレクトリ名:clipboard_image_paste

# cd plugins
# unzip /tmp/clipboard_image_paste-1.4.zip
#

ディレクトリ名の変更

# mv clipboard_image_paste-1.4 clipboard_image_paste

Redmine Issue Importer

CSV形式ファイルに記述された情報をチケットに登録/更新するプラグイン。

Ver.1.2.2は、Redmine 2.2.xに対応しています。

ディレクトリ名:redmine_importer

# cd plugins
# unzip /tmp/redmine_importer-1.2.2.zip
#

ディレクトリ名の変更

# mv redmine_importer-1.2.2 redmine_importer

データベース作成

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
  :
#

テーマ

Redmineは、テーマをインストールすることによって見栄えを変更することができます。

テーマの変更は、[管理]>[設定]>[表示]で、テーマ欄にインストールされているテーマから選択します。

Farend basic

「日本語環境でRedmineの画面を見やすくすることを目的としたテーマ」

Farend fancy

「Farend basicにアイコン追加・色の微調整をしたテーマ」

# cd public/themes
# unzip /tmp/redmine_theme_farend_fancy-master.zip
# mv redmine_theme_farend_fancy-master farend_fancy
#

Wiki編集中のフォントが等幅ではない

原因がよく分からないが、public/themes/farend_fancy/stylesheets/application.css の次の記述を修正して暫定対処。

 input[type="text"] {
-  font-family: "Osaka-Mono", "MS Gothic", sans-serif;
   font-size: 100%;
 }

 textarea.wiki-edit {
-  font-family: "Osaka-Mono", "MS Gothic", sans-serif;
   letter-spacing: normal;
   line-height: 130%;
 }

行頭の-を付けた行を削除します。

Gitmike

Githubっぽいテーマ

アップデート

Redmineのバージョンアップに、データやファイル、プラグインなどを一緒に追従させる手順です。

Redmine本体のバージョンアップ

以下に、redmine-2.1.4から2.2.1へのアップデートを例に手順を示します。

サービスの停止

バージョンアップ作業中にデータが更新されないよう、サービスを停止します。

# service httpd stop

MySQLは移行作業時に稼働している必要があるので停めません。

Redmineソースの入手と展開

バージョンアップしたRedmineのソースを、/var/lib/redmine-バージョン番号に展開します。

# cd /var/lib
# tar xzf /tmp/redmine-2.2.1.tar.gz
# ls -l
  :
lrwxrwxrwx.  1 root    root     13 12月  1 22:42 2012 redmine -> redmine-2.1.4
drwxrwxr-x. 17 apache  apache 4096 12月  2 02:44 2012 redmine-2.1.4
drwxrwxr-x. 16    1000   1000 4096 12月 20 22:59 2012 redmine-2.2.1
  :
#

シンボリックリンクは最後に変更するので、ここではこのままです。

設定ファイルのコピー

現在稼働している設定ファイルをコピーしてきます。

# cp redmine/config/database.yml redmine-2.2.1/config/
# cp redmine/config/configuration.yml redmine-2.2.1/config/
#

プラグインのコピー

# cp -pr redmine/plugins/* redmine-2.2.1/plugins/

注記) プラグインはバージョン依存があり得るので、アップデートのやり方は悩ましいです。実際、いろいろエラーが起きるところで、また、対処がケースバイケースです。

テーマのコピー

標準以外の追加したテーマがあればコピーします。

# ls redmine-2.2.1/public/themes
README  alternate  classic
# rsync -av --exclude alternate --exclude classic redmine/public/themes/ \
redmine-2.2.1/public/themes/
#

添付ファイルのコピー

# cp -p redmine/files/* redmine-2.2.1/files/

bundleの実行

バージョンアップにより必要なgemファイルが増減した、指定バージョンが変わった、gemがバージョンアップしている、などの事象があるため、gemファイルは前のバージョンをコピーせず、新規にbundleを実行します。

まず、bundlerがバージョンアップしていれば追従します。この実行例は、バージョンアップがなかった場合です。

# gem update bundler --no-rdoc --no-ri
Updating installed gems
Nothing to update
#

Gemfile.localを作っていればコピーします。

# cp redmine/Gemfile.local redmine-2.2.1 
#

bundlerを実行します。

# cd redmine-2.2.1
# bundle install --path vendor/bundler --without development test postgresql sqlite
Fetching gem metadata from http://rubygems.org/.........
Fetching gem metadata from http://rubygems.org/.........
Fetching gem metadata from http://rubygems.org/.........
Fetching gem metadata from http://rubygems.org/..
Fetching gem metadata from http://rubygems.org/..
Fetching gem metadata from http://rubygems.org/..
Installing rake (10.0.3)
Installing i18n (0.6.1)
 :(中略)
Your bundle is complete! It was installed into ./vendor/bundler
#
bundle installでエラー

今回、プラグインの関係でエラーが発生したのでメモ

# cd redmine-2.2.0
# bundle install --path vendor/bundler --without development test postgresql sqlite
Fetching gem metadata from http://rubygems.org/.........
 :(中略)
Installing xapian-full (1.2.3) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
  :(中略)
checking for uuid/uuid.h... no
checking for uuid.h... no
configure: error: Neither uuid/uuid.h nor uuid.h found - required for brass, chert
 and flint (you may need to install the uuid-dev, libuuid-devel or e2fsprogs-devel package)
rake aborted!
 :
# 

Redmine 2.1.4にDMSFプラグインを入れていたのですが、2.2.0のbundle install時にオプション --without xapian を指定しなかったので、xapian-full gemをインストールしようとしてその際エラーになりました。bundleの--without にxapianを追記するか、あるいはこの際入れてしまうかです。

エラーを見ると、uuid.hファイルが見つからないため、ネイティブのビルドが失敗した、OSのパッケージでuuid-devかlibuuid-develかe2fsprogs-develあたりが不足してるのでは?、とのメッセージです。

yumでuuid-develを調べると、未インストールの次のパッケージがありました。

# yum list | grep uuid-devel
libuuid-devel.i686                       2.17.2-12.7.el6_3              updates
libuuid-devel.x86_64                     2.17.2-12.7.el6_3              updates
uuid-devel.i686                          1.6.1-10.el6                   base
uuid-devel.x86_64                        1.6.1-10.el6                   base
#

ここは、uuid-develをいれてみます。

# yum install uuid-devel
  :
# rpm -ql uuid-devel
/usr/bin/uuid-config
/usr/include/uuid.h
/usr/lib64/libossp-uuid.so
/usr/lib64/pkgconfig/ossp-uuid.pc
/usr/share/man/man3/ossp-uuid.3.gz
#

さて、bundleの再実行をします。

# bundle install --path vendor/bundler --without development test postgresql sqlite
 :(中略)
checking for uuid_create... no
configure: error: uuid.h found, but uuid_create() not found.  You probably wants to
 install libuuid from util-linux-ng or e2fsprogs (you may need to install the uuid-dev,
 libuuid-devel or e2fsprogs-devel package)
rake aborted!

エラーです。一歩すすみましたが、uuid_create関数が見つからないというエラーです。

次の候補のlibuuid-develを入れてみます。

# yum install libuuid-devel
  :
# rpm -ql uuid-devel
/usr/bin/uuid-config
/usr/include/uuid.h
/usr/lib64/libossp-uuid.so
/usr/lib64/pkgconfig/ossp-uuid.pc
/usr/share/man/man3/ossp-uuid.3.gz
#

bundleを再々実行します。

# bundle install --path vendor/bundler --without development test postgresql sqlite
 :(中略)
Your bundle is complete! It was installed into ./vendor/bundler
#

時間がかかりましたが成功しました。今回物理メモリ1GBの環境で実行してますが、ビルド中にメモリが足りずスワッピングが発生していたためです。mysqldを止めてメモリの空きを増やし対処。

セッション鍵の作成

# bundle exec rake generate_secret_token

注記) mysqldが起動していないとエラーになります。

データベースの更新(移行)

# bundle exec rake db:migrate RAILS_ENV=production

プラグインの移行

# bundle exec rake redmine:plugins:migrate RAILS_ENV=production
Migrating redmine_absolute_dates (Redmine Absolute Dates plugin)...
Migrating redmine_assets_plugin (Redmine Assets plugin)...
Migrating redmine_code_review (Redmine Code Review plugin)...
Migrating redmine_dmsf (DMSF)...
Migrating redmine_parking_lot_chart (Redmine Parking Lot Chart plugin)...
Migrating redmine_wiki_extensions (Redmine Wiki Extensions plugin)...
Migrating redmine_work_time (Redmine Work Time plugin)...

#

Passengerの設定

ビルドします。

# bundle exec passenger-install-apache2-module
Welcome to the Phusion Passenger Apache 2 module installer, v3.0.12.
  :
Press Enter to continue, or Ctrl-C to abort.
  :
# 

設定ファイルは上書きします。

設定ファイルの記述を更新します。

# bundle exec passenger-install-apache2-module --snippet >> /etc/httpd/conf.d/passenger.conf
# vi /etc/httpd/conf.d/passenger.conf
 :(追記したsnippet行の古い記述を削除)
#

Pasasengerのパラメータ設定

Passerngerを動作させる環境によってはパラメータをデフォルトから変更した方が良い場合があります。

パラメータ名  概要  デフォルト値  変更例 
PassengerMaxPoolSize
Ruby on Railsのプロセス最大起動数  メモリ256MB環境なら2、2GB環境なら30 
PassengerPoolIdleTime  この時間(秒)アクセスがないとアプリケーションを終了させる 300  アクセス時に数十秒待たされるので、3600とか43200とか 
       

サービスの起動

ファイルパーミッションの変更

# chown -R apache.apache .

シンボリックリンクの切り替え

# cd ..
# rm redmine
# ln -s redmine-2.2.0 redmine

バージョンアップ作業中にデータが更新されないよう、サービスを停止します。

# service httpd start

バックアップ

Redmineデータのバックアップは、データベースと添付ファイルが対象となります。

データベースのバックアップ

MySQLのバックアップとなります。論理バックアップとローバックアップがありますが、サイズがそれほど大きくない場合は論理バックアップが手軽です。ここではmysqldumpコマンドによる論理バックアップを示します。

mysqldumpコマンドによるバックアップ

mysqldumpは、オンライン中でも実施できるバックアップです。次に実行例を示します。

$ mysqldump -uroot -pxxxx redmine > redmine_mysql.dump

データベース名をredmineとしていた場合の例です。mysqldumpコマンドは結果を標準出力に吐き出すので、リダイレクトでファイルに格納します。テキスト(DDL文とINSERT文)形式でかなりの容量になるので、長期間保持する場合、圧縮した方がよいでしょう。

ダンプしたデータベースの復元

mysqldumpでダンプしたデータを復元するときは、復元先のMySQLからredmineデータベースを削除してから行います。

$ mysql -uroot -pxxxx
mysql> DROP DATABASE redmine;
mysql> CREATE DATABASE redmine;
mysql>
$ mysql -uroot -pxxxx redmine < redmine_mysql.dump
  :

注意点

バックアップしたRedmineと、復元するRedmineとでプラグイン構成が違う場合、プラグインがデータベーススキーマに手を入れているとRedmineの実行時にエラーとなることがあります。

ファイルのバックアップ

RedmineでチケットやWikiなどに添付したファイルはデータベースには格納されず、ファイル専用ディレクトリに格納されます。

その時点ですべてのファイルを一括バックアップするなら、tarでまとめてしまいます。定期的にバックアップする場合、差分だけ更新するのにrsyncを使うと便利です。

tarコマンドによるバックアップ

$ cd /var/lib/redmine/files
$ tar czf ~/redmine_files.tgz
$

tarアーカイブしたファイルの復元

$ cd /var/lib/redmine/files
$ tar xzf ~/redmine_files.tgz
$

Redmine設定

ユーザー認証

Active Directoryユーザーで認証したい

Windows OSでユーザー管理に使われるActive Directoryを、Redmineから利用してユーザー認証することができます。

設定は、[管理] > [LDAP認証] で [新しい認証方式] をクリックします。設定画面で、必要な設定を記述します。

項目  設定内容  例 
名称   このLDAP認証を識別する任意の名称  Walesドメイン認証
ホスト   Active Directoryサーバーのホスト名  mabinogi.local
ポート   Active Directoryサーバーのポート番号  389
アカウント   Active Directoryに登録されているユーザー名  Wales\pryderi
パスワード   上述ユーザーのパスワード  Passw@rd
検索範囲   ユーザー情報が格納されるディレクトリパス  DC=mabinogi,DC=local
LDAPフィルタ     
タイムアウト(秒単位)     
合わせてユーザーを作成   チェックを入れると初回自動でRedmineにユーザー登録  チェック
ログイン   Active Directoryでログイン名が格納される属性  sAMAccountName
名前  Active Directoryで使用者の名が格納される属性  givenName
苗字  Active Directoryで使用者の苗字が格納される属性  sN
メールアドレス   Active Directoryで使用者のメールアドレスが格納される属性  mail

設定後、Redmineのログインで、ユーザー名、パスワードを入力すると、Redmineに新規ユーザーとして作成されます。

リポジトリ

信頼できない認証局のSubversionリポジトリにつなぎたい

Subversionリポジトリへ正規の認証局でないSSL接続が必要な場合、Redmineは404エラーとして扱いますが、それをちゃんと見れるようにします。(そもそもオレオレ認証が問題なのですが・・・)

まず、CentOSに一般ユーザーでログインし、Redmineのリポジトリ設定で使用するユーザー名/パスワードで件のSubversionリポジトリにアクセスします。

$ svn list --username redmine https://svn.example.com/repos/foo
'https://svn.example.com:443' のサーバ証明書の認証中にエラーが発生しました:
 - 証明書は信頼のおける機関が発行したものではありません。証明書を手動で認証
   するためにフィンガープリントを用いてください!
 :(中略)
拒否しますか (R)、一時的に承認しますか (t)、常に承認しますか (p)? p
認証領域: <https://svn.example.com:443> Authorization Realm
'redmine' のパスワード:

ここで「常に承認 (p)」を実施後、一般ユーザーのホームディレクトリにある.subversionディレクトリを、apacheユーザーのホームディレクトリ(/var/www)にコピーします。

# cp -r ~foo/.subversion /var/www
# chown -R /var/www/.subversion

Gitリポジトリを構築しRedmineユーザーで認証する

Redmineのプロジェクトから参照するGitリポジトリを、HTTPアクセス可能とし、ユーザー認証をRedmineユーザー認証で行うことができます。詳細を次のページに書きました。

セキュアな通信

HTTPSで通信する

Apache+Passengerでhttps接続する設定です。

passenger.confに次の設定を追記します。

<Location /redmine>
SSLRequireSSL
</Location>

mod_sslをインストールします。

# yum install mod_ssl

iptables(ファイアウォール)の設定にポート443(HTTPS)を追加します。

# iptables -L --linenumber
  :(設定追加行番号を確認する)
# iptables -I INPUT 6 -m state --state NEW -m tcp -p tcp --dport https -j ACCEPT
# iptables -L
  :(設定内容を確認する)
# service iptables save
注:INPUTの後ろの6はiptablesの追加箇所が6行目のときです。

ここまでの設定でhttpsで接続できるようになりますが、正規の証明書がないとWebブラウザで接続するときに危険警告が表示されます。

トラブルシュート

レスポンスが異様に遅い

最初のアクセス時、ブラウザに画面が表示されるまで時間がかかる

httpdサービスを起動後の初回、およびしばらく誰もアクセスしなかった場合、Passengerプロセスが起動していないため、アクセス時にPassengerプロセスの起動を行います。このため、ちょっと(10〜30秒くらい?)待たされます。

途中あるときからレスポンスが遅くなる、再起動したら大丈夫

いろいろな原因があります。

添付したサイズの大きなファイルをダウンロードしたら、以降レスポンスが遅い

Redmineに添付した数百MBのファイルをダウンロード以後Redmineの操作のレスポンスが異様に重い現象が発生しました。調べると、httpdプロセスの使用メモリがどんどん増大し、空きメモリがなくなりスラッシングが発生した場合です。

この処置は、mod_xsendfileを使ってファイル転送を行うことで回避できます。

# yum install mod_xsendfile
RequestHeader Set X-Sendfile-Type X-Sendfile
XSendFile on
XSendFilePath /var/lib/redmine-2.2.1/files
注記)XSendFilePathに指定するパスはシンボリックではなく実パスである必要があります。
--- production.rb.1     2013-01-09 23:14:30.000000000 +0900
+++ production.rb       2013-01-13 16:54:46.526430816 +0900
@@ -29,4 +29,7 @@
   config.action_mailer.logger = nil

   config.active_support.deprecation = :log
+
+  # Specifies the header that your server uses for sending files
+  config.action_dispatch.x_sendfile_header = "X-Sendfile"
 end
Passengerの使用メモリが増大しスワップが発生

Passengerがメモリ喰いなので(原因は、Ruby や Ruby on Rails やアプリケーションにあったりしますが)、メモリが少ない(<2GB)マシンでは長時間運用していたりアクセスが多数発生すると生じることがあります。

CentOS 6、Ruby 1.9.3で動かしているとき、Passengerのプロセスは物理メモリ常駐サイズが100MB強、Apacheのプロセス(の1つ)httpdが70MB、MySQLが50MBと合計220MBほど喰っていました。物理メモリが1GBだと余裕がない状況です。

リポジトリを設定後、リポジトリをクリックしたときにいつまでも応答が返ってこない

かなり使い込まれたリポジトリ(Subversion、コミット数は数千、ファイル数は数千)を新たに設定して、プロジェクトのリポジトリをクリックした際、1時間以上たっても応答なし状態でした。原因はOSの空きメモリがなくスラッシングが発生(物理メモリ2GB)。物理メモリを3GBに増加させたら十数分後に応答が返りました(VMware Workstation上で仮想化したCent OS 6、運用中に物理メモリを増加させられた)。

別なサーバーを用いる

Apache + Passenger の組み合わせ以外に使われているのは、Nginx + Unicorn です。

Unicornサーバー

RailsサーバーのUnicornを設定します。Unicornは、Rackアプリケーションを実行するためのHTTPサーバーで、クライアントへの効率的な応答(速さ、低遅延)を目的として設計されています。

マスター/ワーカープロセス構造で、プルリクエスト(空いているワーカープロセスが要求を処理する)モデルです。1ワーカープロセスは1つの要求を処理します。

インストール

Unicornは、gem形式で提供されています。そこで、RedmineのGemfile.localに記述し、Redmine固有にインストールします。

<redmineインストールディレクトリ>/Gemfile.local を作成

gem "unicorn"

bundlerの更新をします。

redmine-2.2.2$ bundle update
    :
Installing kgio (2.8.0) with native extensions
    :
Installing raindrops (0.10.0) with native extensions
    :
Installing unicorn (4.5.0) with native extensions
    :
redmine-2.2.2$ 

コマンドラインからの実行

動作確認のため、フォアグラウンドプロセスとして起動します。ファイアウォール(iptables)は一時停止しておきます。

redmine-2.2.2$ bundle exec unicorn_rails -l 8081 -E production
I, [2013-01-27T05:35:14.310828 #3784]  INFO -- : listening on addr=0.0.0.0:8081 
fd=9
I, [2013-01-27T05:35:14.311120 #3784]  INFO -- : worker=0 spawning...
I, [2013-01-27T05:35:14.312275 #3784]  INFO -- : master process ready
I, [2013-01-27T05:35:14.313212 #3787]  INFO -- : worker=0 spawned pid=3787
I, [2013-01-27T05:35:14.313359 #3787]  INFO -- : Refreshing Gem list
/var/lib/redmine-2.2.2/vendor/bundler/ruby/1.9.1/gems/activesupport-3.2.11/lib/a
ctive_support/dependencies.rb:251:in `block in require': iconv will be deprecate
d in the future, use String#encode instead.
I, [2013-01-27T05:35:20.964454 #3787]  INFO -- : worker=0 ready

コマンドラインオプションは次です。

--listen -l [アドレス:]ポート
ソケットのエンドポイントを指定
--config-file -c ファイル
設定ファイルを指定
-D
デーモンプロセス起動指定
-E <RAILS_ENV>
production等を指定

フォアグラウンドプロセスとして起動した場合、Ctrl-Cで停止します。
デーモンプロセスとして起動した場合、シグナルINT(強制終了)またはQUIT(グレースフル停止)をマスタープロセスに送ります。

デーモンプロセスに対する設定ファイル再読み込みトリガーはシグナルHUP、プログラム(Ruby)をデプロイしたらシグナルUSR2を送ります。

マスタープロセスのプロセスIDは、次のように調べます。

$ pgrep -f 'unicorn_rails master'
3783
$

設定ファイル

ネットをあちこちと漁って、見よう見まねで作成した設定ファイルです。

<redmineインストールディレクトリ>/config/unicorn.rb を作成

# ワーカープロセスの数。1ワーカーで1つのリクエストを処理する。
# ワーカー数が上限に達すると、先行するリクエストが完了するまで待ちとなる。
worker_processes 2

# タイムアウト秒数
timeout 120

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

# 稼働中のプロセスのPIDを書いておくファイル。
pid "tmp/pids/unicorn.pid"
# デーモンで起動すると標準出力/標準エラー出力が/dev/nullになるので、
# それぞれログファイルに出力する。
stderr_path 'log/unicorn.stderr.log'
stdout_path 'log/unicorn.stdout.log'

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

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

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
  begin
    uid, gid = Process.euid, Process.egid
    user, group = "redmine", "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

起動ファイル/etc/init.d/unicorn を作成

set -e

sig () {
  test -s "$PID" && kill -$1 `cat "$PID"`
}

oldsig () {
  test -s "$OLD_PID" && kill -$1 `cat "$OLD_PID"`
}

cmd () {

  case $1 in
    start)
      sig 0 && echo >&2 "Already running" && exit 0
      echo "Starting"
      $CMD
      ;;
    stop)
      sig QUIT && echo "Stopping" && exit 0
      echo >&2 "Not running"
      ;;
    force-stop)
      sig TERM && echo "Forcing a stop" && exit 0
      echo >&2 "Not running"
      ;;
    restart|reload)
      sig USR2 && sleep 5 && oldsig QUIT && echo "Killing old master" `cat $OLD_PID` && exit 0
      echo >&2 "Couldn't reload, starting '$CMD' instead"
      $CMD
      ;;
    upgrade)
      sig USR2 && echo Upgraded && exit 0
      echo >&2 "Couldn't upgrade, starting '$CMD' instead"
      $CMD
      ;;
    rotate)
            sig USR1 && echo rotated logs OK && exit 0
            echo >&2 "Couldn't rotate logs" && exit 1
            ;;
    *)
      echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
      exit 1
      ;;
    esac
}

setup () {

  echo -n "$RAILS_ROOT: "
  cd $RAILS_ROOT || exit 1
  export PID=$RAILS_ROOT/tmp/pids/unicorn.pid
  export OLD_PID="$PID.oldbin"
  CMD="bundle exec unicorn_rails -c config/unicorn.rb -E $RAILS_ENV -D"
}

start_stop () {

  # either run the start/stop/reload/etc command for every config under /etc/unicorn
  # or just do it for a specific one

  # $1 contains the start/stop/etc command
 # $2 if it exists, should be the specific config we want to act on
  if [ $2 ]; then
    . $2
    setup
    cmd $1
  else
    for CONFIG in /etc/unicorn/*.conf; do
      # import the variables
      . $CONFIG
      setup

      # run the start/stop/etc command
      cmd $1
    done
   fi
}

ARGS="$1 $2"
start_stop $ARGS

/etc/unicorn/redmine.conf

RAILS_ENV=production
RAILS_ROOT=/var/lib/redmine

自動起動設定(chkconfig)

/etc/init.d/unicorn に次を追記し

# chkconfig: 345 83 17
# description: unicorn is a HTTP rack application server.

自動起動(chkconfig)に登録します。

# chkconfig --add unicorn
# chkconfig unicorn on
# chkconfig --list unicorn
unicorn         0:off   1:off   2:on    3:on    4:on    5:on    6:off
# 

問題解決

大きなサイズのファイルを添付したらエラー

数百MB以上のサイズのファイルを添付しようとすると、UnicornプロセスがKillされてしまいます。ログにはタイムアウトによるエラーが記録されています。

E, [2013-01-16T23:44:19.525947 #4734] ERROR -- : worker=0 PID:4739 timeout (61s > 60s), killing

ファイルを添付すると、いったん/tmpの下にファイルを生成し、それからそのファイルを<Redmineディレクトリ>/filesにコピーする動きをするので、時間がかかってタイムアウトが発生するようです。

<redmineインストールディレクトリ>/config/unicorn.rb にタイムアウト値(秒数)を追記して対処します。

timeout 1000

Nginx

HTTPサーバー兼リバースプロキシーです。

インストール

CentOS用のRPMパッケージが用意されています。

# rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-
release-centos-6-0.el6.ngx.noarch.rpm
# yum install nginx
    :
Installing:
 nginx          x86_64          1.2.4-1.el6.ngx            nginx          361 k
    :
#

/etc/nginx 下に設定ファイル群が、/etc/init.d/nginxに起動スクリプトが、/usr/sbin/nginxに実行ファイルがインストールされます。

また、nginxユーザー/nginxグループが生成されます。

設定

Nginxの設定は、/etc/nginx/nginx.confと、そこからインクルードされる/etc/nginx/conf.d/*.conf に記述します。

インストール直後の状態では、/etc/nginx/conf.dの下にはdefault.confがあります。このディレクトリにRedmine/Unicorn用設定ファイルを追加します。

/etc/nginx/nginx.conf

この設定ファイルはデフォルトでよいかと思います。

もし、Redmineの利用者が多数(数百以上)いるサーバーであれば、worker_processes の設定値をデフォルトの1から、CPU数(コア数、4コア8スレッドのXeonプロセッサなら4)に増やすとよいようです。

サーバーが同時にクライアントからの接続を受け付けられる数は、worker_processes × woker_connections で算出されます。デフォルト設定値では、1 × 1024 です。

/etc/nginx/conf.d/redmine.conf
upstream unicorn-redmine {
    server unix:/tmp/unicorn_redmine.sock;
}
server {
    listen 8087;
    server_name _;
    root /var/lib/redmine/public;
    try_files $uri/index.html $uri.html $uri @app;

    location @app {
        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_redirect off;
        proxy_pass http://unicorn-redmine;
    }

    error_page 500 502 503 504 /500.html;

    location /500.html {
        root /var/lib/redmine/public;
    }

}

server { ... } に、Nginxに振る舞わせる定義を記述します。

listen行は、ポート8087に来た要求に対処することを指定します。
server_name行は、HTTP要求のサーバー名が合致した場合にこのserver {...}設定が有効であることを指定します。なお、_は何にでも合致するようです。
root行は、ドキュメントルートを指定します。シンボリックリンク/var/lib/redmineが実体/var/lib/redmine-2.3.0などを指しているものとします。
try_files行は、リクエストしたリソース(ファイル)が実在する場合、以降のプロキシ処理をせずに戻します。これで、静的コンテンツに対するリクエストをunicornに委譲せずnginxが直接返します。
location @app は、unicornに委譲する処理を記載しています。
location /500.htmlは、エラーが発生した時のページを定義しています。

設定のテスト

nginxには設定ファイルのチェックをする-tオプションがあります。

# nginx -t
  :

設定ファイルは各行(各ディレクティブ)の末尾にセミコロンが必須ですが、よく忘れて起動エラーとなります。そこで、事前チェックを勧めます。

設定(URLにディレクトリ指定)

Passengerで、http://server.example.com/redmine のURLでRedmineをアクセスしていたように、Nginxでもディレクトリを使いたい場合の設定をメモします。ほぼ、次の記事を参考にしています。

Passengerのとき同様、/var/www/htmlの下に、redmineというシンボリックファイルを作成しておきます。

upstream unicorn-redmine {
    server unix:/tmp/unicorn_redmine.sock;
}
server {
    listen 8088;
    server_name _;
    root /var/www/html;

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

    location @unicorn_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;
        proxy_pass http://unicorn-redmine;
    }
}

実行

nginxはマスタープロセスとワーカープロセスから構成され、マスタープロセスはroot権限で実行、ワーカープロセスはnginxユーザー権限で実行します。

問題解決

ファイルを添付しようとしたら、「413 Request Entity Too Large」エラー

/etc/nginx/conf.d/redmine.conf に追記

server {
    client_max_boxy_size 1024M;
    :
}
nginxの起動に失敗: bind() to 0.0.0.0:80 failed (98: Address already in use)
# service nginx start
nginx を起動中: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
                                                           [失敗]

Nginxをインストールすると、デフォルトでポート80を使用します(/etc/nginx/conf.d/default.conf)。別途apache(CentOSのサービス名はhttpd)が起動する設定になっていると、ポート80が競合します。

この場合、Nginxのデフォルト設定(/etc/nginx/conf.d/default.conf)のポート番号を80から別な番号に変更するか、このファイル自体を削除します。

HTTPS(SSL)で通信

nginxを使ってHTTPSで通信する設定です。HTTPS化にあたっては、

というアプローチがあります。後者については、なるほどなぁと思いました。

完全にHTTPSで通信する設定

通常の設定で使用するポート番号をHTTPSの443に変更し、SSL設定を追記します。

upstream unicorn-redmine {
    server unix:/tmp/unicorn_redmine.sock;
}

server {
    listen 443;
    server_name _;

    ssl on;

    root /var/lib/redmine/public;
    proxy_redirect off;

    try_files $uri/index.html $uri.html $uri @app;

    location @app {
        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_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        proxy_pass http://unicorn-redmine;
    }

    error_page 500 502 503 504 /500.html;

    location /500.html {
        root /var/lib/redmine/public;
    }
}

証明書、秘密鍵などの指定をしていない最低限の設定です。

apache+passenger v.s. nginx+unicorn

Apacheのabコマンドを使用した性能比較を実施してみました。同一マシン上でKVM上にそれぞれ立ち上げて、同一マシンの第3のKVM上からabコマンドでアクセスをして計測しました。

$ ab -n 100 -c 10 -A admin:admin http://ホスト名/issues/1

Redmine 2.1.2 Apache Passenger - 2.52 [#/sec]

Redmine 2.1.2 Nginx Unicorn - 3.57 [#/sec]

参考情報

インストール手順の参考としたページ

Gemfile.localにpassengerを記載してbundleでインストールする手順の参考としたページ

HTTPサーバー/Railsサーバーの選択にあたり参考としたページ

SELinuxとRedmineに関する参考情報

Passenger

このページに、以下の記述がある。

Notes

I would suggest to stick with Passenger 2.2.15.
While it's possible to get 3.0.2 working it will flood your audit log with denials.