先日公開した 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 認証が求められるようになります。上記の場合は、username
と password
で認証します。