Vagrantで構築した仮想マシンへredmineを構築する手順


結構はまったのでメモを残す。

やりたかったことは、vagrantで構築した仮想マシン上へバージョンアップやプラグインの確認用のredmineを作成したかった。

## 前提環境
OS: OS X 10.9.2(Marvericks)
Mem: 4GB
ruby: 2.0.0-p343(rbenv)
vagrant: 1.4.3
chef-solo: 11.10.2

## 事前の準備
vagrant、chef-soloのインストール
[今っぽい Vagrant + Chef Solo チュートリアル](http://qiita.com/taiki45/items/b46a2f32248720ec2bae)を参考にしました。
boxには、CentOS6.5を使用しました。
ついでに、Berkshelf+Chef Soloの環境も整えておきます。

vagrantユーザでsshログインができるようになっていればOK。
このままのOSの状態だとロケーションがUTCになっていました。ので、これも変更しておきます。(これもcookbookにしておくべきか？)

```
$ sudo cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```
dateコマンドでJSTとなっていればOK。

これで、cookbookを作成する環境が整いました。

## Cookbook作成
1. rubyのインストール

	rbenv環境のrubyをインストールする。

	``` [chef-repo]/Berksfile
	site :opscode
	
	cookbook 'ruby_build'
	cookbook 'rbenv', github: "fnichol/chef-rbenv"
	```
	chef-rbenvを利用して、rbenv環境を構築する。
	インストールは、1.9系、2.0系および2.1系をインストールしてお	いた。インストールバージョンは、お好みで。

	```[chef-repo]/site-cookbooks/ruby/recipes/install.rb
	include_recipe "rbenv::system"
	include_recipe "ruby_build"
	
	rbenv_ruby "1.9.3-p484"
	rbenv_ruby "2.0.0-p353"
	rbenv_ruby "2.1.0"
	rbenv_global "1.9.3-p484"
	
	# rbenvグループを作成して /usr/local/rbenv
	# の実行権限をvagrantユーザに追加する
	group "rbenv" do
		action :create
		members "vagrant"
		append true
	end
	
	# インストールしたrbenvのグループを変更する
	execute "change install ruby group" do 
		command "chown -R :rbenv /usr/local/rbenv"
		action :run
	end
	
	# 各rubyバージョンにbundlerをインストールする
	rbenv_gem "bundler" do
		rbenv_version "1.9.3-p484"
	end
	rbenv_gem "bundler" do
		rbenv_version "2.0.0-p484"
	end
	rbenv_gem "bundler" do
		rbenv_version "2.1.0"
	end
	
	###
	### デフォルトのBox設定では、kernel関連の
	### パッケージがインストールされないように
	### 設定されているので、その制限を解除しておく。
	### kernel-develパッケージがインストールできないため。
	###
	file '/etc/yum.conf' do
		_file = Chef::Util::FileEdit.new(path)
			_file.search_file_replace_line('exclude=kernel', 		'#exclude=kernel¥n')
		content _file.send(:contents).join
		action :create
	end.run_action(:create)
	```

	さらに、この設定がないとcookbookに落としてきた外部のrecipe	が実行できません。ここに関しての情報が少なくはまりました。

	```[chef-repo]/site-cookbooks/ruby/metadata.rb
	:
	:
	depends 'ruby_build'
	depends 'rbenv'
	```

1. mysqlのインストール

	ここでも外部レシピを使用するので、Berksfileに以下を追加する。

	``` [chef-repo]/Berksfile
	:
	:
	cookbook 'mysql'
	cookbook 'database'
	:
	:
	```

	redmine用にmysqlをインストールします。確認用なので、サクッとインストールと設定だけを行います。

	``` [chef-repo]/site-cookbooks/redmine-mysql/recipes/install.rb
	include_recipe "mysql::server"
	
	cookbook_file "/etc/mysql/conf.d/mysql.cnf" do
		souce "mysql.cnf"
		mode 0644
		notifies :restart, "service[mysql]", :immediately
	end

	include_recipe "database::mysql"

	# コネクション定義
	mysql_connection_info = {
		:host => "localhost",
		:username => "root",
		:password => node['mysql']['server_root_password']
	}

	# redmine用のデータベース作成
	mysql_database "db_redmine" do
		connection mysql_connection_info
		action :create
	end
	
	# redmine用データベースのユーザを作成
	mysql_database_user "user_redmine" do
		connection mysql_connection_info
		password "xxxxxxxx"
		database_name "db_redmine"
		privileges [:all]
		action [:create, :grant]
	end
	```

	このレシピにもdependsを追加

	```` [chef-repo]/site-cookbooks/redmine-mysql/metadata.rb
	:
	:
	depends 'mysql'
	depends 'database'
	```

1. passengerのインストール

	外部レシピのpassenger_apache2を使用して、passengerのインストールを行おうとしたのですが、ここで問題が発生しました。
	rbenv環境のrubyをしようしてpassengerのconfを生成しようと四苦八苦したのですが、結局うまくいかず、passenger_apache2のレシピをコピーするような形で独自のレシピを作成して対応しました。
	こういう場合、どう対応するのがいいのでしょうか？うまい解決法がわからんなぁ。
	passengerのコンパイルとhttpdのインストールはここで実行します。

	```[chef-repo]/Berksfile
	:
	:
	cookbook 'passenger_apache2'
	:
	:
	```

	apache2のレシピを使用するために、Berksfileに追加しておく。

	```[chef-repo]/site-cookbooks/passenger/recipes/install.rb
	include_recipe "apache2"
	
	include_recipe "build-essential"
	node.default['passenger']['apache_mpm'] = "prefork"

	case node['platform_family']
	when "arch"
		package 'apache'
	when "rhel"
		package "httpd-devel"
		if node['platform-family'].to_f < 6.0
			package 'curl-devel'
		else
			package 'libcurl-devel'
			package 'openssl-devel'
			package 'zlib-devel'
		end
	else
		apache_development_package = if %w( worker threaded ).include? node['passenger']['apache_mpm']
					'apache2-threaded-dev'
				else
					'apache2-prefork-dev'
				end
		%W( #{apache_development_package} libapr1-dev libcurl4-gnutls-dev ).each do |pkg|
			package pkg do
				action :upgrade
			end
		end
	end

	rbenv_gem "passenger" do
		version node['passenger']['version']
	end

	rbenv_script "passenger_module" do
		code <<-CODE
			passenger-install-apache2-module --auto
		CODE
	end

	ruby_block "passenger variables set" do
		block do
			#テンプレートの設定値をrbenvのパスへ上書きする
			passenger_version = "#{Chef::Recipe::PassengerConfig.build_directory_for_version(node['passenger']['version'])}"
			node.default['rbenv']['gems_dir'] = %x[ source /etc/profile; /usr/local/rbenv/bin/rbenv exec gem environment gemdir ].chomp
			node.default['passenger']['root_path'] = "#{node['rbenv']['gems_dir']}/gems/passenger-#{node['passenger']['version']}"
			node.default['passenger']['module_path'] = "#{node['passenger']['root_path']/#{passenger_version}/apache2/mod_passenger.so"
		end
	end

	template "#{node['apache']['dir']/mods-available/passenger.load" do
		cookbook "passenger"
		source "passenger.load.erb"
		owner "root"
		group "root"
		mode 0644
	end

	template "#{node['apache']['dir']/mods-available/passenger.conf" do
		cookbook "passenger"
		source "passenger.conf.erb"
		owner "root"
		group "root"
		mode 0644
	end

	link "#{node['apache']['dir']}/mods-enabled/passenger.load" do
		to "#{node['apache']['dir']}/mods-available/passenger.load"
	end
	
	link "#{node['apache']['dir']}/mods-enabled/passenger.conf" do
		to "#{node['apache']['dir']}/mods-available/passenger.conf"
	end
	```

1. redmineのインストール
	[Redmine 2.5をCentOS 6.5にインストールする手順](http://blog.redmine.jp/articles/2_5/installation_centos/)を参考にレシピを作成。
	
	```[chef-repo]/site-cookbooks/redmine/recipes/install.rb
	# 設定
	REDMINE_HOME = "/var/lib/redmine"
	REDMINE_VERSION = "2.3-stable"

	# ImageMagick,ヘッダファイル,日本語フォント類のインストール
	package "ImageMagick" do
		action :install
	end
	package "ImageMagick-devel" do
		action :install
	end
	package "ipa-pgothic-fonts" do
		action :install
	end
	package "libuuid-devel" do
		action :install
	end
	package "wget" do
		action :install
	end

	# redmineをSVNリポジトリからダウンロードする
	subversion "redmine" do
		repository "http://svn.redmine.org/redmine/branches/#{REDMINE_VERSION}"
		destination "#{REDMINE_HOME}"
		action :sync
	end

	template "#{REDMINE_HOME}/config/configuration.yml" do
		owner "root"
		mode 0644
		source "configuration.yml.erb
	end

	template "#{REDMINE_HOME}/config/database.yml" do
		owner "root"
		mode 0644
		source "database.yml.erb"
	end
	
	# redmineで使用するgemパッケージをインストールする
	rbenv_script "bundle install" do
		cwd "#{REDMINE_HOME}"
		code %{bundle install --without development test --path vendor/bundle}
	end

	# redmineの初期設定を行う
	rbenv_script "init redmine" do
		cwd "#{REDMINE_HOME}"
		code <<-EOC
			bundle exec rake generate_secret_token
			RAILS_ENV=production bundle exec rake db:migrate
		EOC
	end

	# redmineのディレクトリをapacheユーザへ変更
	execute "change redmine dir" do
		cwd "#{REDMINE_HOME}"
		command "chown -R apache:apache #{REDMINE_HOME}"
	end

	# railsアプリケーションとしての設定
	include_recipe "rails"

	web_app "redmine" do
		cookbook "passenger"
		template "web_app.conf.erb"
		docroot "#{REDMINE_HOME}/public"
		servername "hogehoge"
		server_alias ["fugafuga", "hogefuga"]
		rails_env "production"
	end
	```
	
	テンプレートの設定
	内容はほぼ固定で適当に記述してあるが、将来的に可変にできるとよろしいでしょう。

	```[chef-repo]/site-cookbooks/redmine/templates/default/configuration.yml.erb
	production:
		email_delivery:
			delivery_method: :smtp
			smtp_settings:
				address: "localhost"
				port: 25
				domain: "vagrantup.com"

		rmagick_font_path: /usr/share/fonts/ipa-pgothic/ipagp.ttf
	```

	```[chef-repo]/site-cookbooks/redmine/templates/default/database.yml.erb
	prodcution:
		adapter: mysql2
		database: db_redmine
		host: localhost
		username: user_redmine
		passowrd: [password]
		encoding: utf8
	```

	ここでもdependsの設定を追加する
	
	```[chef-repo]/site-cookbooks/redmine/metadata.rb
	:
	:
	depends 'rails'
	depends 'passenger_apache2'
	depends 'redmine-mysql'
	```


	最後に、node.jsonにつらつらと実行するレシピを書いて実行します。
	結構時間がかかりますが、rubyの構築からredmineのインストールまでひととおり行えます。
	はまりどころは、rbenvを使用してpassengerのコンパイル、インストールを行おうとすると、chef-soloで使用しているrubyが使用されて思うようにいかなかったところです。ここに関しての解決方法がもう少し、スマートにできるといいのですが。

## 参考にさせていただいたサイト
大変有意義な情報ありがとうございます。

* [Chef で rbenv + Passenger の環境を構築する](http://d.hatena.ne.jp/suer/20130522/chef_rbenv_passenger)
* [fnichol / chef-rbenv](https://github.com/fnichol/chef-rbenv)
* [sstephenson / rbenv](https://github.com/sstephenson/rbenv)
* [Redmine 2.5をCentOS 6.5にインストールする手順](http://blog.redmine.jp/articles/2_5/installation_centos/)