FIVETEESIXONE

Heroku の Rails でステージング環境を作る


先日公開した yochiyochi-pingping のステージング環境を作りました。

yochiyochi-pingping は Heroku 上で運用しています。が、ローカルの開発環境では、GitHub の OAuth 用のアプリケーション登録すらしていません。なので、修正したときには、ろくに動作確認もせずにいきなり Live に push してうまく動くことを祈る、というメチャクチャなやり方をしていました。しかし、利用してくれている人もいるので、さすがにこれじゃマズいだろう、ってことで、Live と同じ Heroku 上にステージング環境を作ることにしました。

Heroku にステージング用のアプリを作る

Heroku でのステージング環境の構築は、調べてみるといくつか方法があるようで、Heroku アプリをそのまま fork して複製することもできるようです。当然、Live と ステージング環境は同様の環境であることが望ましいので、fork するのは良い方法でしょう。ただ、私の場合は、New Relic や Heroku Scheduler などのアドオン設定を個別に分けたかったので、手動で新しい Heroku アプリを作成する、という方法にしました。

Heroku アプリの作成

新たに「yochiyochi-pingping-staging」の名前で Heroku アプリを作成し、remote には「staging」の名前で登録します。

$ heroku create yochiyochi-pingping-staging --remote staging

注意としては、1つのリポジトリに複数の Heroku アプリが登録された状態になるので、Heroku のコマンドを実行するときはアプリを指定する必要があります。例えばログを確認する heroku logs だとこうです。

$ heroku logs --app yochiyochi-pingping-staging

Live 環境の remote の登録名を変更する

ステージング環境を「staging」として remote に登録したので、それに合わせて、Live の登録名をデフォルトの「heroku」から「production」に変更します (.git/config を直接編集)。

.git/config

...

# [remote "heroku"] から変更
[remote "production"]

...

環境構成ファイルの作成

ステージング環境の Rails アプリは、固有の staging という環境で動かすことにします。ステージング環境の構成は Live と同じにするので、config/environments/production.rb を複製して作成します。

$ cp config/environments/production.rb config/environments/staging.rb

Heroku 環境変数 (RACK_ENV/RAILS_ENV) の設定

RACK_ENV と RAILS_ENV を staging に設定します。

$ heroku config:add RACK_ENV=staging RAILS_ENV=staging --remote staging

Gemfile の変更

Gemfile で、「production」がインストール対象になっているところに、「staging」も対象になるように設定を追加します。

...

# 以下を変更
# group :production do
group :production, :staging do
  gem 'pg'
  gem 'rails_12factor'
end

...

ステージング環境へのデプロイ

以下でデプロイします。

$ git push staging master

一方、Live へデプロイするときには以下のようにします。

$ git push production master

db:migrate

db:migrate をしたら、ステージング環境は完成です。

$ heroku run rake db:migrate --app yochiyochi-pingping-staging

Live 環境のデータベースをステージング環境にコピーする

作ったばかりのステージング環境にはデータが入っておらずチェックしにくいので、Live 環境のデータを参照したいことも多いと思います。そのとき、Live のデータベースを直接参照することもできるようですが、ステージング環境用に複製を作った方が安全でしょう。Heroku アプリでは、以下のコマンドを実行するだけで、簡単に Live 環境のデータベースをステージング環境に複製できます。

$ heroku pgbackups:restore DATABASE `heroku pgbackups:url --remote production` --remote staging

※ Live 環境のデータベースをバックアップし、それをステージング環境にリストアすることで複製しています。

Basic 認証の追加

通常、ステージング環境は公開するものではないので、検索エンジンに表示させたくないでしょう。そのために、robots.txt をステージング環境用に用意するという方法もありますが、そもそも公開したくないものなので、サイト全体に Basic 認証をかけてしまっても良いでしょう。Basic 認証がかかっているサイトは検索エンジンのクロール対象になりません。

Rails に Basic 認証を追加する

ApplicationController に、ステージング環境のみで有効になるように Basic 認証用の設定を追加します。認証用のユーザー名とパスワードはコード内に書きたくないので、環境変数から引っぱるようにします。

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base

...

  http_basic_authenticate_with :name => ENV['BASIC_AUTH_USERNAME'], :password => ENV['BASIC_AUTH_PASSWORD'] if Rails.env == "staging"

...

end

Heroku 環境変数の設定

環境変数に Basic 認証用の設定をします。

$ heroku config:add BASIC_AUTH_USERNAME="username" BASIC_AUTH_PASSWORD="password" --app yochiyochi-pingping-staging 

これで、ステージング環境へのアクセスで Basic 認証が求められるようになります。上記の場合は、usernamepassword で認証します。