Heroku DevCenterのMigrating to the Celadon Cedar Stackの超訳です。(訳の意味が全然違っているものになっていたら教えて下さいー)
はじめに
CedarスタックはHerokuのデフォルトランタイムスタックであり、Bambooスタックの後継です。Cedarスタックでは多言語、柔軟なプロセスタイプ、HTTP 1.1をサポートし、コードの自動注入が大幅に少なくなっています。BambooスタックからCedarスタックへ自動的に移行する手段はありませんが、この記事では手動で移行する際に必要な手順と考慮事項の概要を説明します。
移行中2つのHerokuアプリケーションがそれぞれのスタックで存在することになります。移行ではDBデータとHerokuの設定をBambooスタックのアプリからCedarスタックのアプリへコピーし、ルーティングをCedarスタックのアプリに切り替えるといったことをします。
注意
スタックの移行といったアプリケーションへの大きな変更は、最初は常にステージング環境で実施する必要があります。そこで、移行プロセスと新しい環境でのテストを実施する一時的なHerokuアプリケーションを作成することを強くお勧めします。本番環境に影響を与えることなく、新しいスタックで稼働させるために必要な変更を加えることができるためです。あなたのコードがちゃんと動作するようになったら、本番環境に必要な変更を反映(Push)し、移行を実施することができます。
Gitのトピックブランチを作成する
Cedarスタックへの移行の際に施した変更は、適切に管理するために cedar
トピックブランチに分離して保存しましょう。
$ git checkout -b cedar
Switched to a new branch 'cedar'
Ruby1.9.2との互換性を確保する
CedarスタックではRuby1.9.2を使用しますが、Bambooスタックでは1.8.7、1.9.1、1.9.2を利用することができました。Cedarスタックへ本番環境をアップグレードする前に、Ruby1.9.2で動作することを確認して下さい。Rubyのバージョン変化に伴う文法の変更や、1.9.2でのエンコーディング問題を解決して下さい。
アプリケーションが bamboo-mri-1.9.2
で動作していない場合は、まずこのスタックへ移行することが最初のステップになります。BambooスタックのままRuby1.9.2へ移行しましょう。
$ heroku stack:migrate bamboo-mri-1.9.2
-----> Preparing to migrate bamboo-app
bamboo-ree-1.8.7 -> bamboo-mri-1.9.2
...
-----> Migration prepared.
Run 'git push heroku master' to execute migration.
$ git push heroku master
...
-----> Heroku receiving push
-----> Migrating from bamboo-ree-1.8.7 to bamboo-mri-1.9.2
...
-----> Migration complete, your app is now running on bamboo-mri-1.9.2
Ruby1.9.2で完全に動作するようアプリケーションをテストしましょう。
Specify dependencies
アプリケーションサーバを選択する
Bambooスタックでは全てのアプリケーションがThinで動いていました。依然としてこのアプリケーションサーバの利用を推奨していますが、強制で設定されることはありません。アプリケーションサーバを設定しましょう。Thinを使う場合はGemfileに以下の行を追加します:
gem 'thin'
訳注
後で出てきますがアプリケーションサーバとしてThinを使用するためにProcfileも設定する必要があります。
Postgres
Cedarスタックでは自動的に pg
Gemが設定されないため、Postgresを利用するアプリケーションはGemfileで設定する必要があります。
gem 'pg'
データベースの設定情報(Credential)はSlugコンパイル時に自動設定されます。config/database.ymlにDATABASE_URLを自動的に設定します。
New Relic
Bambooスタックでは config/newrelic.yml
ファイルがNew Relicのプラグインにより自動作成されていましたが、Cedarスタックでは作成されません。
もしBambooスタックでNew Relicを利用しているなら、手動で newrelic_rpm
Gemを Gemfile
に追加します。
gem 'newrelic_rpm'
そして config/newrelic.yml
をNew Relicのテンプレートから作成します。
$ curl https://raw.github.com/gist/2253296/newrelic.yml > config/newrelic.yml
Sendgrid
CedarスタックではSendgridアドオンの設定も自動的に構成されなくなります。RailsアプリケーションがSendgridでメール配信する設定になっているなら、以下のメール初期化設定を config/initializers/mail.rb
に設定する必要があります。
$ curl https://raw.github.com/gist/1690653/mail.rb > config/initializers/mail.rb
HTTP caching plugin
caches_page_via_httpプラグインはVarnishに透過的なキャッシングを提供するためにBambooスタックに自動的にインストールされます。VarnishはCedarスタックのデフォルトではないため、このプラグインは自動注入されなくなります。
ほとんどのCedarアプリケーションではこのプラグインは必要ありませんが、必要な場合は手動でインストールすることができます。
$ script/plugin install https://github.com/pedro/caches_page_via_http.git
Commit dependencies
Cedarスタックへのデプロイのために、この時点までに行われた変更をGemの依存関係の変更を含めコミットします。
Bundlerを実行して新しいGemをインストールします。
$ bundle install
Fetching source index for http://rubygems.org/
Using rake (0.8.7)
...
Gitに新しいファイルをステージします。
$ git add config/newrelic.yml
変更をコミットします(カレントのブランチは ceadr
トピックブランチです)
$ git commit -a -m "Modified application dependencies for Heroku/Cedar compatability"
Procfileを作成する
ProcfileはHerokuアプリケーション上でどのようなプロセスを動かすべきか定義している、Cedarスタックで新たに設定するファイルです。
Bambooスタックでバックグラウンドワーカープロセスを使用していないアプリケーションは、シングルWebプロセスタイプで、アプリケーションのルートに新しく Procfile
を作成します。
web: bundle exec thin start -p $PORT -e $RACK_ENV
バックグラウンドワーカープロセスを使用している場合は worker
プロセスを Procfile
に設定します。
web: bundle exec thin start -p $PORT -e $RACK_ENV
worker: bundle exec rake jobs:work
(webプロセス以外のプロセスについてはカスタムラベルをつけることができます。)
ProcfileはHeroku固有のマニフェストではありません。ローカルでの開発中にもForeman Gemを利用してアプリケーションのプロセス編成を調整するために使用することができます。
$ gem install foreman
Fetching: foreman-0.38.0.gem (100%)
Successfully installed foreman-0.38.0
プロジェクトディレクトリの.env
ファイルに環境変数を設定しておくと、Foremanで実行した際に実行時の環境変数に含まれるようになります。RACK_ENV
をdevelopmentにするよう設定してみましょう。あくまでローカルで使用するため、.env
はコミットしないようにしましょう。(.gitignoreに含めておきます)
$ echo "RACK_ENV=development" >>.env
.env
に設定した環境変数、Procfile
のプロセス設定、そしてForemanを利用し、ローカルでアプリケーションを実行することができます。
$ foreman start
10:01:59 web.1 | started with pid 3484
10:01:59 worker.1 | started with pid 3485
Foremanを利用してローカルでアプリケーションが動作したら、Procfile
をトピックブランチにコミットしましょう。
$ git add Procfile
$ git commit -a -m "Added Procfile to define app's process-formation on Heroku/Cedar"
Cedarアプリケーションを作成する
BambooからCedarに自動的に移行する手段はないため、新しいアプリケーションはCedarスタック上に作成される必要があります。リモートのGitリポジトリをheroku-cedar
といった名前にしておくと、アプリケーションがBambooバージョンなのかCedarバージョンなのか区別がつきやすくなります。
$ heroku create --remote heroku-cedar cedar-app
Creating cedar-app... done, stack is cedar
http://cedar-app.herokuapp.com/ | git@heroku.com:cedar-app.git
Git remote heroku-cedar added
デプロイ
変更したコードベースをCedarアプリケーションにデプロイしても、現在Bamboo上で動作しているアプリケーションに影響を与えることはありません。アプリケーションを単にステージングして機能検証を行う機会を得ることができます。
cedar
トピックブランチから、heroku-cedar
リモートリポジトリのmaster
ブランチに、Cedar互換のソースをデプロイのためPushしましょう。
$ git push heroku-cedar cedar:master
Counting objects: 67, done.
...
-----> Heroku receiving push
-----> Rails app detected
...
アドオンを再構成する
アドオンをどこかのアプリケーションから他のアプリケーションへ移動する方法が現在サポートされていません。全てのアドオンはBambooアプリケーションから手動でCedarアプリケーションに構成される必要があります。
現在Bambooアプリケーションに割り当てられている全てのアドオンのリストをaddons.txt
ファイルに保存します。
$ heroku addons --app bamboo-app > addons.txt
$ more addons.txt
memcache:5mb
newrelic:standard
pgbackups:auto-month
shared-database:5mb
heroku-postgres:ronin
HerokuのPostgresデータベース(heroku-postgresql:XXX)を持つアプリケーションは、この方法でアドオンDBを再作成するべきではないため、addons.txt
から削除します。
$ more addons.txt
memcache:5mb
newrelic:standard
pgbackups:auto-month
shared-database:5mb
xargs
ユーティリティでCedarアプリケーションにアドオンを構成します。
$ cat addons.txt | tr '\n' '\0' | xargs heroku addons:add --app cedar-app
-----> Adding memcache:5mb to cedar-app
...
Bambooアプリケーションに存在するアドオンのグレードによっては、予期せずして不必要な費用が発生するかも知れないことを留意して下さい。
設定変数をコピーする
アプリケーションに設定されている変数も同じく自動的に移行することはできないため、手動でコピーする必要があります。
設定変数をBambooアプリケーションからconfig.txt
ファイルに保存します。
$ heroku config -s --app bamboo-app > config.txt
$ more config.txt
DATABASE_URL=postgres://u:p@host/db
MEMCACHE_PASSWORD=pass
MEMCACHE_SERVERS=mcX.ec2.northscale.net
MEMCACHE_USERNAME=pp123%40heroku.com
RACK_ENV=production
PATH=vendor/bundle/ruby/1.9.1/bin:/usr/local/bin:/usr/bin:/bin
SESSION_SECRET=secret
SHARED_DATABASE_URL=postgres://u:p@host/db
手動で設定されている変数のみ保持する必要があります。アドオンの設定や、MEMCACHE_
、DATABASE_URL
といったHerokuの設定をconfig.txt
を開いて削除して下さい。
データベースの設定やアドオンの設定を上書きしてしまうと、予期せぬ影響が発生する可能性があるため、このような設定を確認して存在していたらconfig.txt
から削除しておきましょう。
$ more config.txt
RACK_ENV=production
SESSION_SECRET=secret
これらアプリケーション固有の設定をCedarアプリケーションに追加しましょう。
$ cat config.txt | tr '\n' ' ' | xargs heroku config:add --app cedar-app
Adding config vars and restarting app... done, v32
RACK_ENV => production
SESSION_SECRET => secret
もし何かヤバいことが起こったら、heroku release:rollback
で素早く元に戻すことができます。
Cedarアプリケーションに息を吹き込む
この段階でBambooアプリケーションと同一の構成である、Cedarで実行中のアプリケーションのコピーがあるはずです。移行への最後のステップでは、CedarアプリケーションにBambooアプリケーションからデータを転送し、ライブトラフィックを受け取れるようにCedarアプリケーションを有効化します。
転送中に何らかのデータ変更が加えられてしまわないよう、データの整合性を確保するため、両方のアプリケーションをメンテナンスモードにします。
$ heroku maintenance:on --app bamboo-app
Maintenance mode enabled.
$ heroku maintenance:on --app cedar-app
Maintenance mode enabled.
Postgres
HerokuのPostgresデータベースプランを利用するアプリケーションは、最小限のダウンタイムを達成するために「Fast database changeover strategy」を使用する必要があります。これらの手順はShared Databaseに格納されているデータを使用するアプリケーションのためのものです。
--
Heroku PG Backupsアドオンはアプリケーション間の素早いデータ移行を実現します(詳しい情報はこちらを参照して下さい)。それぞれのアプリケーションにこのアドオンを追加します(無料で使用できます)。
$ heroku addons:add pgbackups --app bamboo-app
Adding pgbackups to bamboo-app... done
$ heroku addons:add pgbackups --app cedar-app
Adding pgbackups to cedar-app... done
Bambooアプリケーションのデータをバックアップします。
$ heroku pgbackups:capture --app bamboo-app
SHARED_DATABASE (DATABASE_URL) ----backup---> b040
Capturing... done
Storing... done
新しいCedarアプリケーションにバックアップをインポートします。
$ heroku pgbackups:restore DATABASE `heroku pgbackups:url --app bamboo-app` --app cedar-app
SHARED_DATABASE (DATABASE_URL) <---restore--- b040.dump
...
Retrieving... done
Restoring... done
MongoDB, Xeround等のDB系アドオンを使用している場合
それぞれのアドオンのドキュメントを見てね!
カスタムドメイン
カスタムドメインからルーティングされるトラフィックは引き続きBambooアプリケーションを指しています。カスタムドメインが有効になっている場合は、Cedarアプリケーションに追加する前に、Bambooアプリケーションから削除する必要があります。
Bambooアプリケーションからカスタムドメインのリストを取得してdomains.txt
に保存し、カスタムドメインを削除します。
$ heroku domains --app bamboo-app | grep -v "Domain names" > domains.txt
$ more domains.txt
secure.mydomain.com
www.mydomain.com
$ heroku domains:clear --app bamboo-app
Removed all domain names for bamboo-app
Cedarアプリケーションにカスタムドメインを追加します。
$ cat domains.txt | xargs heroku domains:add --app cedar-app
SSL
カスタムドメインと同じように、SSLサポートはBambooアプリケーションからCedarアプリケーションに転送される必要があり、アプリケーションのDNS設定の更新を伴います。様々なSSL製品がBambooスタックで提供されているため詳細はそれぞれのドキュメントを参照して下さい。
メンテナンスモードを解除する
アクセスを受け付けるためCedarアプリケーションのメンテナンスモードを解除します。また、適切な数にdyno数をスケールさせます(Bambooアプリケーションのレベルと合わせると良いでしょう)。
$ heroku dynos --app bamboo-app
bamboo-app is running 5 dynos and 2 workers
$ heroku ps:scale web=5 worker=2 --app cedar-app
Scaling web processes... done, now running 5
Scaling worker processes... done, now running 2
$ heroku maintenance:off --app cedar-app
Maintenance mode disabled.
訳注
スケール数は各々で調整して下さい! このまま実行すると合計7dyno動いちゃいますよ!
最後に
Cedarアプリケーションが動き、稼働状況も特に問題なさそうだと判断したらmaster
ブランチにcedar
ブランチをマージしましょう。
$ git checkout master
$ git merge cedar
Bambooアプリケーションはコスト削減のために退役させましょう。1dynoにスケールダウンさせ、アドオンも有料のものから無料のものへと切り替えましょう。並行稼動の期間中に問題が発生したら、Bambooアプリケーションにロールバックさせることもできます。
免責事項
(一応。。)この訳文を参考にオペレーションを行った場合にもし何らかの損害が発生したとしても責任は負いかねますので、各自の判断でご使用下さい。