初めてRedmine環境を構築したらSCM連携で躓いた話

#初めに。
今までALMiniumを利用していたのですが、CentOS7でコマンドやらミドルやら色々変更となったため、そのままでは動かない模様。。。
新しいモノ好きとしてはどうしてもCentOS7で環境を整えてみたい！ということで、初めてRedmine環境を構築してみました。
<font color="e0e0e0">そして初投稿してみました。。。</font>

**環境**
CentOS7 on VirtualBox
Redmine3.0.2
etc...

##参考元
環境構築に当たっては以下のサイトを参考にしました。
これだけで、Redmine、jenkinsが利用でき、httpsだったり、nginxだったりと、とても良い感じの環境が仕上がります。

* [RedmineをCentOS 7上で動かすーUnicornとNginx編 - ソフトウェアエンジニアリング - Torutk](http://www.torutk.com/projects/swe/wiki/Redmine%E3%82%92CentOS_7%E4%B8%8A%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99%E3%83%BCUnicorn%E3%81%A8Nginx%E7%B7%A8)
* [ラフなひとこと: nginxとJenkinsで CI サーバーを作る](http://rough-and-ready-co-jp.blogspot.jp/2015/04/nginxjenkins-ci.html)
* [Redmineでセキュアなログイン - ソフトウェアエンジニアリング - Torutk](http://www.torutk.com/projects/swe/wiki/Redmine%E3%81%A7%E3%82%BB%E3%82%AD%E3%83%A5%E3%82%A2%E3%81%AA%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3)
* [nginx で http でのアクセスを https にリダイレクト - Qiita](http://qiita.com/kga/items/e30d668ec1ac5e30025b)
* [RedmineとSubversion・Git・Mercurialのリポジトリ（ともに同じCentOSサーバ上）の連携（リポジトリの作成とアクセス・認証） | misty-magic.h](https://mistymagich.wordpress.com/2011/10/19/redmine_and_subversion-git-mercurial-repository/)

#SCM連携で躓いた話(本題)

せっかく上記のサイトで環境を構築できたのですが、SCM連携を設定していると、設定画面でエラーになるやら、プロジェクト作成後エラー画面になるやらで、連携が上手くいきませんでした。。。


##1.Redmineの『[SCM Creator (+Github)](http://www.redmine.org/plugins/redmine_scm)』Pluginが上手く動かない！
本来の目的はRedmineのアカウントでリポジトリの認証ですが、やはりプロジェクト作成時に勝手に作られて欲しいです。
今回Redmine3で環境構築しましたが、Redmine3ではrails4を採用したため、正規表現の文法が従来よりも厳しくなっているとの事。
ログを見ると正規表現の式を修正するか、オプションを付加すれば良い様ですが、ログから修正箇所を探そうにも、java感覚で見た場合、エラーの場所が出力されている感じではなく、自力での修正はほぼ不可能でした。

これ実はダウンロードページにあるプラグインではなく、リポジトリにあるプラグインを利用すれば問題無く動きます。
どうやらrev.141でredmine3.xに対応していたようです。

```
svn export -r 142 http://subversion.andriylesyuk.com/scm-creator redmine_scm
```

##2.Redmineのアカウントでリポジトリの認証が上手く出来ない！
これはmod_perlがインストール出来なくなっていた点と、認証でエラーが出る点で躓きました。
mod_perlについてはこれを利用しない方法もあるようですが、自分の環境では上手くいきませんでした。どうやらepelを使えるようにするとyumでインストール出来るようになるようです。

```
# yum install epel-release
# yum install mod_perl per
```

認証エラーについては、AuthUserFileの設定が必要だったようです。RedmineのDBを参照するため記載の無いところが多かったのですが、自分の環境では必要でした。

```text:
# Subversion
<Location /repos/svn>
  DAV svn
  SVNParentPath "/var/www/repos/svn"

  AuthType Basic
  AuthName "Redmine SVN Repository"
  AuthUserFile /dev/null
  Require valid-user

  #PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler

  RedmineDSN "DBI:mysql:database=redmine;host=localhost"
  RedmineDbUser "redmine"
  RedmineDbPass "password"
</Location>
```

#構築手順(おまけ)
最後に自分が実施した手順をメモ程度に乗せておきます。詳細な説明は参考元を参照してください。

## VirtualBox用
VirtualBox GuestAdditions及びインストールに必須なパッケージのインストール・アップデート済み

```
# yum install -y gcc make kernel-headers kernel-devel bzip2
# yum update kernel*
```

##MariaDB
MariaDBの導入・設定

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

```diff:/etc/my.cnf.d/server.cnf
[mysqld]
+   character-set-server = utf8
```

```diff:/etc/my.cnf.d/mysql-clients.cnf
[mysql]
+   default-character-set = utf8
+   show-warnings
```

MariaDBの起動・自動起動設定

```
# systemctl start mariadb.service
# systemctl enable mariadb.service
```

MariaDBのユーザ設定
```# mysql -uroot``` パスワード設定済みの場合は```# mysql -uroot -p```

```
MariaDB [(none)]> SELECT user,host,password FROM mysql.user;
+---------+-----------------------+----------+
| user    | host                  | password |
+---------+-----------------------+----------+
| root    | localhost             |          |
| root    | localhost.localdomain |          |
| root    | 127.0.0.1             |          |
| root    | ::1                   |          |
|         | localhost             |          |
|         | localhost.localdomain |          |
+---------+-----------------------+----------+
MariaDB [(none)]> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('password');
MariaDB [(none)]> SET PASSWORD FOR 'root'@'localhost.localdomain' = PASSWORD('password');
MariaDB [(none)]> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('password');
MariaDB [(none)]> SET PASSWORD FOR 'root'@'::1' = PASSWORD('password');
MariaDB [(none)]> SELECT user,host,password FROM mysql.user;
MariaDB [(none)]> quit;
```

##Redmine
Redmineの導入・設定

```
# yum install ruby ruby-devel
```

[Redmine公式ダウンロードページ](http://www.redmine.org/projects/redmine/wiki/Download "Download - Redmine")よりRedmineをダウンロード。(今回は3.0.2)

```
# wget http://www.redmine.org/releases/redmine-3.0.2.tar.gz
# cd /var/lib
# tar zxf ~/redmine-3.0.2.tar.gz
# ln -s redmine-3.0.2/ redmine
```

RedmineのMariaDB接続設定

```diff:/var/lib/redmine/config/database.yml
production:
  adapter: mysql2
  database: redmine
  host: localhost
  username: redmine
  password: password
  encoding: utf8
```

```
# chmod 600 /var/lib/redmine/config/database.yml
```

MariaDBのRedmine接続設定

```
# mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE redmine;
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| redmine            |
| test               |
+--------------------+
MariaDB [(none)]> GRANT ALL ON redmine.* TO 'redmine'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
MariaDB [(none)]> quit;
```

Redmineのその他の設定

```diff:/var/lib/redmine/config/configuration.yml
production:
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: "localhost" 
      port: 25
```

```
# chmod 600 /var/lib/redmine/config/configuration.yml
# useradd redmine
# passwd redmine
# cd /var/lib/redmine
# chown -R redmine.redmine .
```

Rubyの導入・設定

```
# gem list
# gem install bundler --no-rdoc --no-ri
# su redmine
$ cd /var/lib/redmine
$ bundle install --path vendor/bundler --without development test
```

Redmineの初期設定

```
$ bundle exec rake generate_secret_token
$ bundle exec rake db:migrate RAILS_ENV=production
```

Redmineの起動確認。script/railsは使用出来ないとメッセージが出るので

```
$ ruby bin/rails server webrick -e production
```

ループバックアドレスでListenしている挙動なので、```# wget http://127.0.0.1:3000```等で動いている事を確認、```Ctrl + C```で終了。

Unicornの導入・設定

```text:/var/lib/redmine/Gemfile.local
gem "unicorn"
```

```
$ bundle update
```

Redmineの起動確認。以下を実行後、他マシンのブラウザ等から```http://IPアドレス:3000/```にアクセス。```Ctrl + C```で終了。

```
$ su
# firewall-cmd --add-port=3000/tcp
# su redmine
$ bundle exec unicorn_rails -l 3000 -E production
```

unicornの設定については参考元：[RedmineをCentOS 6上で動かすーUnicornとNginx編 - ソフトウェアエンジニアリング - Torutk](http://www.torutk.com/projects/swe/wiki/Redmine%E3%82%92CentOS_6%E4%B8%8A%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99%E3%83%BCUnicorn%E3%81%A8Nginx%E7%B7%A8#Unicorn%E3%81%AE%E8%A8%AD%E5%AE%9A) の設定ファイルを利用させていただきました。

```
$ su
# cd /var/lib/redmine/config/
# wget http://www.torutk.com/attachments/download/299/unicorn.rb
# chown redmine.redmine unicorn.rb
```

相対パスでは動かないので絶対パスで指定

```diff:/var/lib/redmine/config/unicorn.rb
-   listen "/tmp/unicorn_redmine.sock", :backlog => 32
+   listen "/var/lib/redmine/tmp/sockets/unicorn.sock", :backlog => 32
```

```text:/etc/systemd/system/redmine-unicorn.service
[Unit]
Description=Redmine Unicorn Server

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

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

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

Redmineの起動確認。以下を実行後、他マシンのブラウザ等から```http://IPアドレス:8282/```にアクセス。

```
# systemctl start redmine-unicorn.service
# systemctl status redmine-unicorn.service
# firewall-cmd --add-port=8282/tcp
```

unicornの自動起動設定

```
# systemctl enable redmine-unicorn.service
```

#nginx

nginxの導入・設定

```text:/etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
```

```
# yum install nginx
```

Redmine用の設定ファイルを作成

```
# cd /etc/nginx/conf.d
# mv default.conf default.conf.orig
```

```text:/etc/nginx/conf.d/redmine.conf
upstream unicorn-redmine {
    server unix:/var/lib/redmine/tmp/sockets/unicorn.sock;
}

server {
    listen 80;
    server_name _;

    root /var/lib/redmine/public;
    client_max_body_size 1G;

    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://unicorn-redmine;
    }

    error_page 500 502 503 504 /500.html;
}
```

nginxの起動

```
# restorecon redmine.conf
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# firewall-cmd --add-service http --zone=public --permanent
# firewall-cmd --reload
# systemctl enable nginx.service
# systemctl start nginx.service
```

SELinuxに阻まれて起動出来ないため、監査ログから設定を作成し適用する

```
# cd ~
# cat /var/log/audit/audit.log | grep nginx | audit2allow
# cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
# semodule -i nginx.pp
# systemctl start nginx.service
```

Redmineの動作確認。SELinuxがEnforcingなので、監査ログから設定を作成し適用する
ブラウザでRedmine```http://IPアドレス/```にアクセス。Internal errorと表示されるのを確認後以下を実施。
2回ぐらい繰り返すと正常に表示される。(繰り返す度にブラウザでInternal errorを表示させないと設定出来ません。)

```
# cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
# semodule -i nginx.pp
# systemctl restart redmine-unicorn.service
# systemctl restart nginx.service
```

#jenkins

javaとjenkinsの導入・設定

```
# yum install java
# cd /etc/yum.repos.d
# curl -O http://pkg.jenkins-ci.org/redhat/jenkins.repo
# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
# yum install --enablerepo=jenkins jenkins
```

```diff:/etc/sysconfig/jenkins
#
# Options to pass to java when running Jenkins.
#
-   JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
+   JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.util.ProcessTree.disable=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Tokyo"

#
# Port Jenkins is listening on.
# Set to -1 to disable
#
JENKINS_PORT="8080"

#
# Pass arbitrary arguments to Jenkins.
# Full option list: java -jar jenkins.war --help
#
-   JENKINS_ARGS=""
+   JENKINS_ARGS="--prefix=/jenkins"
```

jenkinsの起動・自動起動設定

```
# systemctl start jenkins.service
# chkconfig jenkins on
```

nginxのjenkins用の設定ファイルを作成・転送設定を追加

```text:/etc/nginx/conf.d/jenkins.conf
upstream jenkins_server {
    server 127.0.0.1:8080 fail_timeout=0;
}
```

```diff:/etc/nginx/conf.d/redmine.conf
+       location ~ /jenkins {
+           proxy_redirect     off;
+           proxy_set_header   X-Forwarded-Proto $scheme;
+           proxy_set_header   Host              $http_host;
+           proxy_set_header   X-Real-IP         $remote_addr;
+           proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
+           proxy_set_header   Host $host;
+   
+           proxy_pass         http://jenkins_server;
+       }
```

```
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl restart nginx.service
# systemctl status nginx.service
```

nginxと同様に、SELinuxに阻まれて起動出来ないため、監査ログから設定を作成し適用する
ブラウザでjenkins```http://IPアドレス/jenkins/```にアクセス。Internal errorと表示されるのを確認後以下を実施。

```
# cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
# semodule -i nginx.pp
```

#https化
証明書の作成

```
# openssl req -new -newkey rsa:2048 -sha1 -x509 -nodes -set_serial 1 -days 10950 -subj "/C=JP/ST=Tokyo/CN=www.example.com" -out /etc/pki/tls/certs/www.example.com.crt -keyout /etc/pki/tls/private/www.example.com.key
# cd /etc/nginx/conf.d/
# mv /etc/nginx/conf.d/redmine.conf /etc/nginx/conf.d/redmine_SSL.conf
```

nginxの設定

```diff:/etc/nginx/conf.d/redmine_SSL.conf
server {
-       listen 80;
+       listen 443;
        server_name _;

+       ssl on;
+       ssl_certificate /etc/pki/tls/certs/www.example.com.crt;
+       ssl_certificate_key /etc/pki/tls/private/www.example.com.key;
+   #    ssl_session_timeout 5m;
+   #    ssl_protocols SSLv2 SSLv3 TLSv1;
+   #    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
+   #    ssl_prefer_server_ciphers on;
```

```text:/etc/nginx/conf.d/http.conf
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
```

firewallの設定

```
# firewall-cmd --list-services --zone=public
# firewall-cmd --add-service https --zone=public --permanent
# firewall-cmd --reload
# firewall-cmd --list-services --zone=public
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl restart nginx.service
# systemctl status nginx.service
```

httpでアクセスした場合は自動でhttpsに転送されます。

#SCM連携
リポジトリアクセス用にapacheの導入・必要なモジュールの導入

```
# yum install httpd
# yum install epel-release
# yum install mod_perl perl-DBI perl-Digest-SHA1 perl-Digest-SHA perl-DBD-MySQL mod_dav_svn
```

Redmineプラグインの導入・設定

```
# mkdir -p /var/www/repos/{svn,git,hg}
# chown -R redmine:redmine /var/www/repos
# cd ~
# svn export -r 142 http://subversion.andriylesyuk.com/scm-creator redmine_scm
# mv redmine_scm /var/lib/redmine/plugins/
```

```text:/var/lib/redmine/config/scm.yml
production:
  deny_delete: false
  auto_create: true
  svn:
    path: /var/www/repos/svn
    svnadmin: /usr/bin/svnadmin
    url: https://www.example.com/repos/svn
  git:
    path: /var/www/repos/git
    git: /usr/bin/git
    options: --bare
    url: https://www.example.com/repos/git
    update_server_info: true
    git_ext: true
  mercurial:
    path: /var/www/repos/hg
    hg: /usr/bin/hg
    url: https://www.example.com/repos/hg
development:
```

```diff:/var/lib/redmine/Gemfile.local
+   gem "rails-observers"
```

```
# cd /var/lib/redmine
# bundle update
# bundle exec rake db:migrate:plugin RAILS_ENV=production
# bundle exec rake tmp:cache:clear
# bundle exec rake tmp:sessions:clear
# systemctl restart nginx.service
# systemctl restart redmine-unicorn.service
```

nginxの設定

```text:/etc/nginx/conf.d/apache.conf
upstream apache_server {
    server 127.0.0.1:8086 fail_timeout=0;
}
```

```diff:/etc/nginx/conf.d/redmine_SSL.conf
+       location ~ /repos/ {
+           proxy_redirect     off;
+           proxy_set_header   X-Forwarded-Proto $scheme;
+           proxy_set_header   Host              $http_host;
+           proxy_set_header   X-Real-IP         $remote_addr;
+           proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
+           proxy_set_header   Host $host;

+           proxy_pass         http://apache_server$request_uri;
+       }
```

```
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl restart nginx.service
```

リポジトリ認証用の設定

```
# mkdir -p /usr/lib64/perl5/vendor_perl/Apache/Authn
# ln -s /var/lib/redmine/extra/svn/Redmine.pm /usr/lib64/perl5/vendor_perl/Apache/Authn/Redmine.pm
```

```diff:/etc/httpd/conf/httpd.conf
-   Listen 80
+   Listen 8086

-   User apache
-   Group apache
+   User redmine
+   Group redmine
```

```text:/etc/httpd/conf.d/redmine.conf
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

PerlLoadModule Apache::Authn::Redmine

# Subversion
<Location /repos/svn>
  DAV svn
  SVNAdvertiseV2Protocol Off
  SVNParentPath "/var/www/repos/svn"
  
  AuthType Basic
  AuthName "Redmine SVN Repository"
  AuthUserFile /dev/null
  Require valid-user
  
  #PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler
  
  RedmineDSN "DBI:mysql:database=redmine;host=localhost"
  RedmineDbUser "redmine"
  RedmineDbPass "password"
</Location>

# Git
SetEnv GIT_PROJECT_ROOT /var/www/repos/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /repos/git/ /usr/libexec/git-core/git-http-backend/
<Location /repos/git>
  AuthType Basic
  AuthName "Redmine Git Repository"
  AuthUserFile /dev/null
  Require valid-user
  
  #PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler
  
  RedmineDSN "DBI:mysql:database=redmine;host=localhost"
  RedmineDbUser "redmine"
  RedmineDbPass "pasword"
  RedmineGitSmartHttp yes
</Location>
```

nginx、jenkinsと同様に、SELinuxに阻まれて起動出来ないため、監査ログから設定を作成し適用する

```
# service httpd start
# cat /var/log/audit/audit.log | grep httpd | audit2allow -m httpd
# grep httpd /var/log/audit/audit.log | audit2allow -M httpd
# semodule -i httpd.pp
# service httpd start
# chkconfig httpd on
```

apacheの動作確認。SELinuxがEnforcingなので、監査ログから設定を作成し適用する
ブラウザ又はクライアントでリポジトリ```http://IPアドレス/repos```にアクセス。Internal errorといった表示がされるのを確認後以下を実施。

```
# cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
# grep nginx /var/log/audit/audit.log | audit2allow -M nginx
# semodule -i nginx.pp
```

apacheの動作確認。SELinuxがEnforcingなので、監査ログから設定を作成し適用する
Redmineに初期管理ユーザでログイン後、管理ページから設定をロード。プロジェクト作成画面でSCMでsvnを選択してプロジェクトを作成。プロジェクトのメンバーに初期管理ユーザを追加する。
ブラウザ又はクライアントでリポジトリ```http://IPアドレス/repos/svn/プロジェクト名/```にアクセス。ブラウザの場合、Could not open the requested SVN filesystemと表示のを確認後以下を実施。

```
# cat /var/log/audit/audit.log | grep httpd | audit2allow -m httpd
# grep httpd /var/log/audit/audit.log | audit2allow -M httpd
# semodule -i httpd.pp
```