「Cloud Foundry 百日行」第36日目は,Ruby-on-Rails ベースの project management ソフト Redmine です。今さら説明の必要のない超有名アプリケーションだと思いますが,これも Cloud Foundry の上で動かすことができます。
基本情報
-
公式サイト
http://www.redmine.org/
(日本語情報: http://redmine.jp/)
手順の概要は以下の通りです。
- 1) ソースコードの取得
- 2) セッション・ストアの秘密鍵の生成
- 3) データベース・サービスの作成とアプリとのバインド
- 4) 初期データ投入に必要な環境変数の設定
- 5) アプリの更新・起動
- 6) 動作確認
1. ソースコードの取得
公式サイトのインストール手順 では, http://www.redmine.org/projects/redmine/wiki/Download から tarball をダウンロードするか,リポジトリーからコードをチェックアウトすると書いてあるので,ここでは GitHub の公式ミラーからソースコードをチェックアウトします。
$ git clone https://github.com/redmine/redmine.git
$ cd redmine
今回は最新の master ではなく,最新安定版 (検証時点では 3.0.4) を使うことにします。
$ git checkout 3.0.4
2. セッション・ストアの秘密鍵の生成
公式サイトのインストール手順には, セッション・ストアの秘密鍵の生成 が含まれています。これはコマンド的には bundle exec rake generate_secret_token
を実行すれば良いのですが,このコマンドを正常に実行する前提条件として,
- Ruby と bundler gem のインストール
bundle install
の実行- config/database.yml が存在すること
が必要になります。
今回は1番目の「Ruby と bundler gem のインストール」は既に終わっているものとして,2番目以降について順次述べていきます。
bundle install
の実行
$ bundle install --path vendor/bundle --without rmagick
--path vendor/bundle
は,ローカルの vendor/bundle ディレクトリーに Ruby の gem をインストールするというオプションです。必須ではありませんが,これを付けないと,この Redmine だけで使う gem が Ruby 全体の gem を入れるディレクトリーにインストールされ,「ライブラリー汚染」の原因になるので,付けたほうが無難です。
--without rmagick
は,rmagick gem のインストールをスキップするためのオプションです。これも必須ではないのですが,これを付けないと rmagick をインストールするために追加のパッケージ (Ubuntu では libmagickwand-dev, imagemagick 等) のインストールが必要になります。今回 Redmine はローカルの環境ではなく Cloud Foundry 上で実行するので,ローカルにこれらのパッケージを入れる必要はありません。つまり bundle exec rake generate_secret_token
を実行できる環境を整えるだけのための bundle install
なので,rmagick のインストールはスキップすることにしました。
config/database.yml の作成
これも,ただ単に形式の整ったファイルが存在すればいいので, config/database.yml.example をコピーするだけでOKです。
$ cp config/database.yml.example config/database.yml
セッション・ストアの秘密鍵の生成
前提が整ったので,本来の目的であるセッション・ストアの秘密鍵生成を行います。
$ bundle exec rake generate_secret_token
config/initializers/secret_token.rb というファイルができていて,内容が以下のようになっていればOKです (当然ですが代入式の右辺値はこの値とは異なるはずです)。
$ cat config/initializers/secret_token.rb
# This file was generated by 'rake generate_secret_token', and should
# not be made visible to public.
# If you have a load-balancing Redmine cluster, you will need to use the
# same version of this file on each machine. And be sure to restart your
# server when you modify this file.
#
# Your secret key for verifying cookie session data integrity. If you
# change this key, all old sessions will become invalid! Make sure the
# secret is at least 30 characters and all random, no regular words or
# you'll be exposed to dictionary attacks.
RedmineApp::Application.config.secret_key_base = '431137b97013042fb346ce3f5517c773d2e7dca562651ab389e81768e52bd9507710f8144437159a'
これでセッション・ストア秘密鍵が生成できました。
3. データベース・サービスの作成とアプリとのバインド
次に,データベース・サービスを作成し,アプリにバインドします。
データベース・サービスの作成
MySQL サービスを作成します。
$ cf create-service p-mysql 100mb my4red
Creating service instance my4red in org nota-ja / space 100 as nota-ja...
OK
アプリを停止状態でプッシュ
サービスとバインドするために,アプリを停止状態でプッシュするのですが,このままプッシュすると vendor/bundle 内のファイルも全てアップロードされてしまいます。Cloud Foundry 側で bundle install
が実行されるため,これらは実際にはアップロード不要なので, .cfignore ファイルを予め作成して,vendor/bundle をアップロード対象から除外します。
$ emacs .cfignore
$ cat .cfignore
vendor/bundle/
アプリを停止状態でプッシュします。
$ cf push redmine --no-start
Creating app redmine in org nota-ja / space 100 as nota-ja...
OK
..
Done uploading
OK
アプリとサービスのバインド
$ cf bind-service redmine my4red
Binding service my4red to app redmine in org nota-ja / space 100 as nota-ja...
OK
TIP: Use 'cf restage redmine' to ensure your env variable changes take effect
4. 初期データ投入に必要な環境変数の設定
公式サイトのインストール手順 に従って,初期データの投入を自動で行うために環境変数 REDMINE_LANG
を予め設定しておきます。これが未設定だと,初期データ投入時に対話的に入力を求められてしまい,Cloud Foundry では入力のすべがないためエラーが発生してしまいます。
$ cf set-env redmine REDMINE_LANG ja
日本語を使用したいので, ja
に設定しました。
Setting env variable 'REDMINE_LANG' to 'ja' for app redmine in org nota-ja / space 100 as nota-ja...
OK
TIP: Use 'cf restage' to ensure your env variable changes take effect
$ cf env redmine
Getting env variables for app redmine in org nota-ja / space 100 as nota-ja...
OK
..
User-Provided:
REDMINE_LANG: ja
..
5. アプリの更新・起動
起動コマンドを設定してアプリを更新・起動します。
$ cf push redmine -c 'bundle exec rake db:migrate && bundle exec rake redmine:load_default_data && bundle exec rails server --port=$PORT' -t 180
ポイントは2つ。
1つは起動コマンドでデータベース・スキーマの設定 (bundle exec rake db:migrate
) と初期データの投入 (bundle exec rake redmine:load_default_data
) を行ったのちに,環境変数で指定された待ち受けポートでアプリを起動する (bundle exec rails server
) こと。
もう1つは,データベース・スキーマの設定にけっこう時間がかかるので,タイムアウトを長めに設定する (-t 180
) ことです。
Updating app redmine in org nota-ja / space 100 as nota-ja...
OK
..
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: redmine.10.244.0.34.xip.io
last uploaded: Thu Jul 23 03:59:09 UTC 2015
stack: cflinuxfs2
buildpack: Ruby
state since cpu memory disk details
#0 running 2015-07-23 01:01:16 PM 0.0% 143.5M of 256M 0 of 1G
アプリが起動しました。
6. 動作確認
ブラウザーでアプリにアクセスしてみます。
公式サイトの情報 に従い,初期ユーザー admin でログインします:
参考情報
今回 Cloud Foundry 上に構築した Redmine はほぼ問題なく使えるのですが,添付ファイル等がローカル・ファイルシステムに保存されるため,再起動したりスケールアウトした時に添付ファイル等へのアクセスに問題が生じます。これを回避するために,添付ファイル等をオブジェクト・ストレージに保存するという方法があります。
今回は検証環境にオブジェクト・ストレージが用意できなかったため試してみることができませんでしたが,ご要望があれば別途試してみたいと思います。
今回使用したソフトウェア
- cf-release (v211)
https://github.com/cloudfoundry/cf-release/tree/v211
(https://github.com/cloudfoundry/cf-release/tree/2121dc6405e0f036efa4dba963f7f49b07e76ffa) - bosh-lite
https://github.com/cloudfoundry/bosh-lite/tree/552dc6869600c5350eb7ffb4fb9c9c5e79e3889d - cf-mysql-release (v20)
https://github.com/cloudfoundry/cf-mysql-release/tree/v20
(https://github.com/cloudfoundry/cf-mysql-release/tree/8f7f6916b75a2e01332cc91df8c285dabe698703) - CF CLI (v6.12.0-8c65bbd-2015-06-30T00:10:31+00:00)
https://github.com/cloudfoundry/cli/tree/v6.12.0
(https://github.com/cloudfoundry/cli/tree/8c65bbd4d243cbbc9bdbf2ec2a3b0e094c094f48) - Redmine (v3.0.4)
https://github.com/redmine/redmine/tree/3.0.4
(https://github.com/redmine/redmine/tree/a49a2c04902c2697a77205f2b66d6ee45c5b368c)