herokuでRedmine(1.2.1)を動かす(後編)

前回 はひとまずローカルでRedmineを動かしてみました。今回はさらにheroku用の修正を加えてデプロイしてみます。

herokuの制約

herokuでRedmine1.2.1を動かす場合、以下の制約が関係してきます。詳細は後ほど触れます。

  1. 書き込みできるのはtmp, logディレクトリ以下のみ
  2. Redmine1.2.1が要求するRails2.3.11が動作するのはbambooスタック
  3. 対話型のRakeタスクは実行できない

heroku gemをインストールする

アプリケーションの管理ツールを提供するheroku gemをインストールします。あわせてherokuアカウントのサインアップと公開鍵の登録がまだであれば済ませておきましょう。

$ gem install heroku

herokuに合わせた修正

herokuの制約に対応するため、以下の修正を加える必要があります。

1. plugin_assetsディレクトリをリポジトリに追加

Railsの起動時にRails Enginesがpublic/plugin_assetsディレクトリを作成しますが、herokuではpublic以下に書き込み権限がありません。Engines.public_directoryを書き込み権限のあるtmp以下に変更することもできますが、plugin_assetsディレクトリはプラグインに含まれる画像などがコピーされる場所なので、ブラウザから参照可能なpublic以下である必要があります。
そこで.gitignoreから以下の行を削除し、ローカルで作成されたディレクトリをリポジトリにコミットしておくことにしました。

/public/plugin_assets

2. session_store.rbをリポジトリに追加

通常の手順でRedmineをデプロイする場合、generate_session_store Rakeタスクでクッキーストアセッション用のsecret値を設定しますが、herokuではこのRakeタスクを実行できません。(これも権限のないconfig/initializers以下にファイルを書き込もうとするから)
今回は リポジトリを第三者に公開しない という前提で、ローカルに作成済のconfig/initializers/session_store.rbをリポジトリにコミットしておくことにします。

# .gitignoreから以下の行を削除
/config/initializers/session_store.rb

3. Attachment.storage_pathをtmp以下に変更

Redmineにアップロードしたファイルの保存場所Attachment.storage_pathも、書き込み権限のないfilesディレクトリがデフォルトなので変更しておきます。config/initializers以下にパッチを置いて、ひとまずtmp以下に保存することにしました。

# config/initializers/change_storage_path.rb
storage_path = File.join(RAILS_ROOT, 'tmp', 'files')
Attachment.storage_path = storage_path
FileUtils.mkdir_p(storage_path) unless File.exist?(storage_path)

なお上記の対応だとcache_classes = falseなdevelopmentモードではRAILS_ROOT/filesを示し続けるのでご注意ください。

※これではファイルアップロードの対応として不十分

前述のとおり tmp以下は永続ストレージとして保証されていません 。上記の対応では「一時的にファイルのアップロード、ダウンロードが動作するように見える」だけです。ファイルアップロードを使う場合は、S3などの外部ストレージに保存するよう改修する必要があります。

コミット

以上の修正をローカルリポジトリにコミットしておきます。コミット対象は以下です。

  • .gitignore
  • config/initializers/change_storage_path.rb
  • config/initializers/session_store.rb
  • public/plugin_assets/

herokuにデプロイ

アプリケーションの登録

まずherokuにアプリケーションを登録します。実行環境であるスタックは、Redmine1.2.1の要件(Rails2.3.11とRuby1.8.7)に合わせてbamboo-ree-1.8.7を指定します。

$ heroku create --stack bamboo-ree-1.8.7

herokuリポジトリにpush

ローカルリポジトリにコミットした内容をherokuリポジトリにpushします。今回は1.2.1-for-herokuというローカルブランチで作業した内容をherokuのmasterブランチにpushするので、以下のように指定します。

$ git push heroku +1.2.1-for-heroku:master

毎回指定するのが面倒な場合は、以下の設定を追加しておけば省略できます。

$ git config --add remote.heroku.push +refs/heads/1.2.1-for-heroku:master
$ git push heroku

タイムゾーンの設定

今回はデータベースに日本標準時で時刻を保存することにします。
heroku実行環境でタイムゾーンを確認したところPDT(太平洋夏時間)でした。

$ heroku console
>> Time.now.zone
=> "PDT"

このままだとデータベースに記録される時刻もPDTになってしまうので、環境変数TZを設定しておくことにします。

$ heroku config:add TZ=Asia/Tokyo
$ heroku console
>> Time.now.zone
=> "JST"

なおUTCで保存する場合は、config/environment.rbに以下の設定を追加したうえでRedmineのユーザー毎にタイムゾーンを設定する必要があります。

config.active_record.default_timezone = :utc

データのセットアップ

run:rakeサブコマンドでRakeタスクを実行し、データベースのスキーマと初期データを設定します。前述のとおり対話型のRakeタスクは実行できないので、環境変数で言語(以下の場合はja)を指定する必要があります。

# マイグレーション
$ heroku run:rake db:migrate

# 初期データの投入
$ heroku run:rake REDMINE_LANG=ja redmine:load_default_data

なお上記2つのRakeタスクを使わず、ローカルデータベースの内容をコピーする方法もあるようです。

ブラウザで開く

以上でデプロイ完了です。openサブコマンドを使ってブラウザからアクセスしてみてください。

$ heroku open

セキュリティ設定

くれぐれもadminユーザのパスワード変更をお忘れなく。プライベートに使う場合はAdministration – Settings – Authenticationメニューから以下の設定をしておくとよいでしょう。

  • “Authentication required”を"ON"
  • “Self-registration”を"disabled"
  • “Lost-password”を"OFF"

対応していないこと

今回の作業では以下について触れていません。必要に応じて設定してください。

おわりに

「なんとなく動く」まではそれほど時間がかかりませんでしたが、Redmine(とRails)の仕様とherokuの制約を調べていくと「これでは不十分」となることが後からみつかりました。何事もそうですが、採用するプラットフォームの仕様をきちんと把握することが重要ですね。

関連エントリ

blog comments powered by Disqus