Help us understand the problem. What is going on with this article?

HerokuでBambooスタックからCedarスタックへアプリケーションを移行する方法

More than 5 years have passed since last update.

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に以下の行を追加します:

Gemfile
gem 'thin'

訳注

後で出てきますがアプリケーションサーバとしてThinを使用するためにProcfileも設定する必要があります。

Postgres

Cedarスタックでは自動的に pg Gemが設定されないため、Postgresを利用するアプリケーションはGemfileで設定する必要があります。

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 に追加します。

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 を作成します。

Procfile
web: bundle exec thin start -p $PORT -e $RACK_ENV

バックグラウンドワーカープロセスを使用している場合は worker プロセスを Procfile に設定します。

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アプリケーションにロールバックさせることもできます。

免責事項

(一応。。)この訳文を参考にオペレーションを行った場合にもし何らかの損害が発生したとしても責任は負いかねますので、各自の判断でご使用下さい。

mah_lab
最近Elmにハマっています。仕事ではRuby on Railsを10年近く触ってます。 お便りはTwitterからお願いします: https://twitter.com/mah_lab
http://blog.mah-lab.com/
sonicgarden
「お客様に無駄遣いをさせない受託開発」と「習慣を変えるソフトウェアのサービス」に取り組んでいるソフトウェア企業
http://www.sonicgarden.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした