アインシュタインの電話番号
2011.02.20
Herokuでステージング環境を作る

プロダクションとステージングのHerokuアプリ

Herokuはフリーミアムモデルを採用しているので、無料範囲内のHerokuアプリ^1であれば、まったく同じ内容のステージング環境を無料で構築することができる。ということをこの記事で知ってなるほどと思ったので、実際にやってみた。

ステージング用Herokuアプリの追加

既にHerokuアプリがあるGitリポジトリに、ステージング環境用にもう一つHerokuアプリを追加する。追加方法は、普通にheroku createするだけ。

$ heroku create heroku-hello-world-staging --remote staging

上記のように--remoteオプションを指定すると、その名前でremote先を追加できる。

$ git remote -v
heroku  git@heroku.com:heroku-hello-world.git (fetch)
heroku  git@heroku.com:heroku-hello-world.git (push)
staging git@heroku.com:heroku-hello-world-staging.git (fetch)
staging git@heroku.com:heroku-hello-world-staging.git (push)

ちなみに、2個目のHerokuアプリの--remoteオプションを省略した場合は、git remoteには何も追加されず、元のHerokuアプリのgit remote情報を上書きしたりもしないので、忘れても大丈夫。

環境変数ENVの変更

次に、Herokuアプリの環境変数ENVのRACK_ENVの値をproductionからstagingに忘れずに変更しておく。この値を使って、本番用かステージング用なのかをコード内で判別する。

$ heroku config:add RACK_ENV=staging --app heroku-hello-world-staging
Adding config vars:
  RACK_ENV => staging
Restarting app...done.

また、ここからは常に、herokuコマンドを使ってステージング用Herokuアプリに対して何かを行う場合は、以下のように--app heroku-hello-world-stagingと指定する必要がある。^2 指定しないと、本番用Herokuアプリの情報を参照・変更してしまうので注意。例えば、今設定したRACK_ENVの値を参照する場合はこんな感じに。

$ heroku config --app heroku-hello-world-staging
BUNDLE_WITHOUT      => development:test
DATABASE_URL        => postgres://aowho...s.com/aowhownobg
LANG                => en_US.UTF-8
RACK_ENV            => staging
SHARED_DATABASE_URL => postgres://aowho...s.com/aowhownobg

このように、Herokuアプリの環境変数ENVは、アプリごとに保持されていて、例えばTwitter BotのOAuth認証用トークンなどを別のものに分けておけるので、全く同じソースコードを本番用アプリ/ステージング用アプリの両方にアップしていても、ENVの設定さえ間違えていなければ、ステージング用Herokuアプリが本番用Twitterアカウントでツイートしてしまう、なんてことは起こらない。

ステージング用をBasic認証

さきほど変更したRACK_ENVの値を使って、ステージング用アプリの方にBasic認証でアクセス制限をかける。SinatraでのBasic認証の使い方は以前の記事を参考にこんな感じで。

configure :staging do
  use Rack::Auth::Basic do |username, password|
    username == ENV['STAGING_BASIC_AUTH_USERNAME'] && password == ENV['STAGING_BASIC_AUTH_PASSWORD']
  end
end

もちろん上記に該当する環境変数の追加を忘れずに。追加先はステージング用のほう。

$ heroku config:add STAGING_BASIC_AUTH_USERNAME="staging" STAGING_BASIC_AUTH_PASSWORD="staging" --app heroku-hello-world-staging
Adding config vars:
  STAGING_BASIC_AUTH_PASSWORD => staging
  STAGING_BASIC_AUTH_USERNAME => staging
Restarting app...done.

最終的に、ステージング用アプリの方の環境変数ENVはこんな感じに。

$ heroku config --app heroku-hello-world-staging
BASIC_AUTH_PASSWORD         => fuga
BASIC_AUTH_USERNAME         => hoge
BUNDLE_WITHOUT              => development:test
DATABASE_URL                => postgres://aowho...s.com/aowhownobg
LANG                        => en_US.UTF-8
RACK_ENV                    => staging
SHARED_DATABASE_URL         => postgres://aowho...s.com/aowhownobg
STAGING_BASIC_AUTH_PASSWORD => staging
STAGING_BASIC_AUTH_USERNAME => staging

デプロイ

デプロイはリモート先をstagingにするだけでおk

$ git commit -am 'create staging enviroment'
$ git push staging master
$ heroku open --app heroku-hello-world-staging
Opening [http://heroku-hello-world-staging.heroku.com/](http://heroku-hello-world-staging.heroku.com/)

ページを開いたら、Basic認証になるはず。問題がなければ本番環境にもデプロイする。

$ git push heroku master
$ heroku open

Herokuで認証付きのステージング環境を構築する - exdesign