herokuでRedmine(1.2.1)を動かす(後編)
前回 はひとまずローカルでRedmineを動かしてみました。今回はさらにheroku用の修正を加えてデプロイしてみます。
herokuの制約
herokuでRedmine1.2.1を動かす場合、以下の制約が関係してきます。詳細は後ほど触れます。
- 書き込みできるのはtmp, logディレクトリ以下のみ
- Heroku | Dev Center | Read-only Filesystem
- 永続ストレージとしての保証もない
- Redmine1.2.1が要求するRails2.3.11が動作するのはbambooスタック
- 対話型の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の制約を調べていくと「これでは不十分」となることが後からみつかりました。何事もそうですが、採用するプラットフォームの仕様をきちんと把握することが重要ですね。