Redmine3.1をCentOS7.1にインストールし、既存のRedmine1.2のデータの移行を行う手順

古いサーバ上でRedmine1.2が動いていたのですが、サーバのリプレースとともにRedmineの移行+Redmine3.1へのアップグレードを行ったので、その手順をメモ。

## 環境

### 移行先サーバ

- OS: CentOS7.1
- DB: MariaDB 5.5.44

### 移行元サーバ

- OS: CentOS5.6
- DB: MySQL 5.0.77
- Redmine 1.2

## 既存のデータの抽出

### ファイルのバックアップ

`(Redmineホーム)/files` 配下にファイルが格納されているため、ディレクトリごとコピーする。
※以下ではRedmineホームを`/var/lib`配下としている

```bash
$ sudo cp -r /var/lib/redmine-1.2.1/files ~/files_bak
```

### DBのダンプ

```bash
$ sudo mysqldump -u {user} -p{password} {db} > ~/mysql.dump
```

これらのデータを一旦ローカルなどに退避しておく。

## 新サーバへRedmineをインストール

基本的には下記のスクリプトを利用し、インストールを行う。 
<https://github.com/farend/redmine-centos7-mariadb-ansible>

※2015/12/16現在、新しいバージョンも公開されているが、新バージョンはDBとしてPostgreSQLを利用している。今回はMySQL(MariaDB)を使いたいため、上記のバージョンを用いる。

### スクリプト実行準備

GitHubのREADMEに従い、スクリプト実行準備を行う。

```bash
$ sudo yum install -y epel-release
$ sudo yum install -y ansible git
$ git clone https://github.com/farend/redmine-centos7-mariadb-ansible.git
```

DBのパスワードを設定。

```bash
$ sudo vi redmine-centos7-mariadb-ansible/group_vars/redmine-servers
```

`db_passwd_root`と、`db_passwd_redmine`を適当な内容に変更する。

### スクリプト実行

スクリプトを実行する。

```bash
$ cd redmine-centos7-mariadb-ansible
$ sudo ansible-playbook -i hosts site.yml
```

当方の環境では、passengerの設定を取得する部分が正常に動作しなかった。
そこで、その部分のみ手動で設定する。

```bash
$ passenger-install-apache2-module --snippet
```

下記のように表示されるので、コピーしておく。
※環境により記述が変化するので、この通りとは限らない。

```bash
LoadModule passenger_module /usr/local/lib/ruby/gems/2.2.0/gems/passenger-5.0.21/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
  PassengerRoot /usr/local/lib/ruby/gems/2.2.0/gems/passenger-5.0.21
  PassengerDefaultRuby /usr/local/bin/ruby
</IfModule>
```

コピーした記述およびその他の設定の記述をApacheのコンフィグに記述する。

```bash
$ sudo vi /etc/httpd/conf.d/redmine.conf

<Directory "/var/lib/redmine/public">
  Require all granted
</Directory>

LoadModule passenger_module /usr/local/lib/ruby/gems/2.2.0/gems/passenger-5.0.21/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
  PassengerRoot /usr/local/lib/ruby/gems/2.2.0/gems/passenger-5.0.21
  PassengerDefaultRuby /usr/local/bin/ruby
</IfModule>

Header always unset "X-Powered-By"
Header always unset "X-Runtime"

PassengerMaxPoolSize 20
PassengerMaxInstancesPerApp 4
PassengerPoolIdleTime 864000
PassengerHighPerformance on
PassengerStatThrottleRate 10
PassengerSpawnMethod smart
PassengerFriendlyErrorPages off
```

### アクセスURLの設定

今回はサブディレクトリ`/redmine`でアクセスできるようにしたい。
Apacheのドキュメントルートに指定されているディレクトリにシンボリックリックを貼る。

```bash
$ sudo ln -s /var/lib/redmine/public /var/www/html/redmine
```

Apacheのコンフィグを変更する。先ほど作成した`redmine.conf`に記述を追加する。

```bash
$ sudo vi /etc/httpd/conf.d/redmine.conf
# 省略

RackBaseURI /redmine

# 省略
```
Apacheを再起動する。

```bash
$ sudo systemctl restart httpd.service
```

### 動作確認

`(サーバのIPアドレス)/redmine`にブラウザからアクセスし、Redmineのトップが表示されることを確認する。

## データの復旧

### ファイルの復旧

退避しておいたfilesディレクトリとMySQLのダンプファイルを新サーバにSCPなどで転送し、`redmine`配下へ移動する。

```bash
$ sudo rm -rf /var/lib/redmine/files
$ sudo mv ~/files_bak /var/lib/redmine/files
```

### DBの復旧

ダンプしたMySQLのデータを流し込む。

```bash
$ mysql -u {user} -p{password} {db} < ~/mysql.dump
```

DBのマイグレーションを行う必要があるが、そのままのテーブル構成だとエラーが発生するため、手動で不要な(マイグレーションにより作成されるはずの)テーブルの削除を行う。

```bash
$ mysql -u {user} -p{password} {db}

mysql> drop table changeset_parents;
mysql> drop table queries_roles;
mysql> drop table custom_fields_roles;
mysql> drop table email_addresses;
mysql> drop table roles_managed_roles;
```

DBのマイグレーションを行う。

```bash
$ cd /var/lib/redmine
$ sudo rake db:migrate RAILS_ENV=production
```

## その他

一部のページへのリクエストで文字コードに起因するエラーが発生するため、アプリケーションコードの修正を行う。


```bash
$ sudo vi var/lib/redmine/app/helpers/application_helper.rb
```

```ruby
# Helper to render JSON in views
  def raw_json(arg)
    arg = force_utf8_strings(arg) #add
    arg.to_json.to_s.gsub('/', '\/').html_safe
  end

# (中略)

private

# (中略)

# add
  def force_utf8_strings(arg)
    if arg.is_a?(String)
      arg.dup.force_encoding('UTF-8')
    elsif arg.is_a?(Array)
      arg.map do |a|
        force_utf8_strings(a)
      end
    elsif arg.is_a?(Hash)
      arg = arg.dup
      arg.each do |k,v|
        arg[k] = force_utf8_strings(v)
      end
      arg
    else
      arg
    end
  end
```

参考：[Redmine カスタムクエリが500 ActionView::Template::Error ("XXX" from ASCII-8BIT to UTF-8) になるときの対処方法](http://qiita.com/toronya/items/145f8be1c69e26ad2b9b)