Heroku addons + Rails Tutorial

## はじめに

AWSを使ってWebサービスを作る人が僕の周りにも増えてきましたが、AWSは自由度が高く、初心者にはかなり扱いにくいと思います。

![heroku](https://d1lpkba4w1baqt.cloudfront.net/heroku-logo-dark-234x60.png) ![rails](http://rubyonrails.org/images/rails.png)

HerokuはAWSにホスティングされたサービスなので、AWSと似たような使い方が出来ます。
なので、いきなりAWSでRailsなどのプログラムを動かすよりも、一度Herokuで運営して経験値をためてみるとよいかと思います。

そこで、Herokuやアドオンを使ったプロジェクト作成手順の一連の流れを大雑把に覚えてみましょう。
(今回は、アジャイル開発を意識して記事を作成しました)

ここで紹介する内容は、AWSで同じことをやるときもAWSのサービスを上手く使えば、ほとんど同様に開発することが出来ます。

なお、Railsのインストール、Herokuのコマンドラインツールなどの導入方法などは[Rails Tutorial](railstutorial.jp)にすべて記載されているので、こちらを参考にしてください。

## 1. Railsプロジェクトの作成
まずは、Railsの新規プロジェクトを作成します。
HerokuのデータベースはPostgreSQLがデフォルトですが、アドオンを使ってMySQLに変更できます。

```shell-session
$ rails new [APP_NAME] -d mysql
```

## 2. Herokuの初期セットアップ
<br>
> このセクションでは、Herokuアプリを新規作成して、データベースをデフォルトのPostgreSQLからMySQLに変更する手順を説明します。

<br>

Railsプロジェクトを作成したら、Herokuのアプリを作成して、HerokuにMySQLのアドオン「 **ClearDB MySQL** 」を追加してみましょう
[HEROKU_APP_NAME]に入れた名前が、サービスのURLの一部になります。（後から管理画面で変更出来ます）

```shell-session
$ heroku create [HEROKU_APP_NAME]
$ heroku addons:add cleardb --app [HEROKU_APP_NAME]
```

clearDBについては、アドオンを追加してもデフォルトのデータベースはPostgreSQLのままです。なので、Herokuの環境設定を変更して、デフォルトのデータベースをMySQLにしてあげましょう。

```shell-session
$ heroku config | grep CLEARDB_DATABASE_URL

-> CLEARDB_DATABASE_URL => mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true
->  ClearDBのURLが表示されるので、mysql://..... をDATABAE_URLにセットする

$ heroku config:set DATABASE_URL='mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true'
-> これで、デフォルトのデータベースがMySQLになった
```

RailsでMySQLをデータベースとして作成するとMySQL2がインストールされますが、HerokuでMySQLを使うためにはMySQLをインストールしないといけません。

```rb:Gemfile
# mysql for heroku production
gem 'mysql'
```

もし、ローカル環境ではSQLite3を使いたい方は、GemファイルにSQLite3を追加して、config/databases.ymlを変更してあげましょう。

```rb:Gemfile
# sqlite3 database for localhost
gem 'sqlite3'
```

```yaml:config/database.yml
development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000

test:
  adapter: sqlite3
  database: db/test.sqlite3
  pool: 5
  timeout: 5000
```

あとはbundle installしてあげればOKです。

章の最後に、herokuにデプロイしてみましょう。

```shell-session
$ git add .
$ git commit -m "initial commit"
$ git push heroku master
```

## 3. 開発環境を整える
<br>
> このセクションでは、Githubにリポジトリを作成し、ステージング環境用のブランチをGitに追加し、最後にHerokuのステージング環境をGitのステージング・ブランチに対応するように設定する方法を説明します。

<br>


さて、一通りHerokuのセットアップが終わりましたが、実際にHeroku上で運営する際に一番怖いのが、「 **変更を本番環境にデプロイしたら動かなくなった！** 」というケースです。

実際にHerokuから離れていく人の多くは、このような悩みからでしょう。
しかし、Herokuでは「 **ステージング環境** 」を作ることが出来ます。

ステージング環境とは、本番用のサーバーと同じ環境で動かしてみて、不具合が無いかをテストするための環境です。

つまり、ステージング環境で予め修正したRailsプログラムの動作を確認しておけば、本番環境でサーバーがストップしてしまう危険性を格段に減らせます。

### ステージング環境の作成

それでは、ステージング環境用のHerokuアプリを新しく作ってみましょう。

```shell-session
$ heroku create [STAGING_APP_NAME]
```

例えば[HEROKU_APP_NAME]が「foo-app」だとすれば、[STAGING_APP_NAME]は「staging-foo-app」とかでいいと思います。

### gitにステージング環境のブランチを追加する

ここで、herokuにデプロイされたプログラムは、gitの **production** というブランチの環境を元に展開されます。
(database.ymlにもproductionって項目ありますよね)

なので、ステージング環境にアプリをデプロイしても、本番環境用のアドオンにアクセスされてしまったりします。そうなると、ステージング環境で色々テストしていると、本番環境に影響が及ぼされる危険性があります。

従って、ステージング環境にデプロイされたら、gitのstagingというブランチの環境にデプロイされるように設定します。
(ここからの設定はちょっと面倒ですが、一度設定すると運営時にプログラムの修正をデプロイや動作確認を行うのが非常に楽になります)


![sourcetree](https://www.atlassian.com/dms/wac/images/press/Atlassian-logos/logoSourcetreePNG.png)

まずは、gitのコマンド打つのが面倒なので、SourceTreeでブランチの管理をしましょう。

私はよくSourceTreeを使ってgitの管理をしていますが、ステージング環境のブランチの作成手順までここに書くと長くなってしまうので、[別の記事にまとめました](http://qiita.com/u651601f/items/627ea3b1362fbe6d25d2)。こちらを参考にしてください。

さて、上記記事では「develop, staging, master」のブランチが作成されましたが、これらのブランチの使い分けは以下のようになります。

|develop branch|staging branch|master branch|
|:-----:|:-----:|:----:|
|ローカルでの開発用|本番にデプロイする前のステージング環境用|本番環境用|

従って開発の流れとしては、 **「ローカル環境で開発したものはdevelopでpush」->「本番前の動作確認用にstagingでpush」->「動作確認が済めばmasterにpush」** といった感じになります。

基本的に開発の殆どは **develop** ブランチで行うと思います。不用意にstagingやmasterブランチでpushしないようにしましょう。
<br>

### Rails + Herokuにstaging環境を設定する
gitのブランチにstagingを追加したので、railsやHerokuの方にもstaging環境を設定していきましょう。

このセクションのはじめに作ったステージング用のHerokuアプリの設定を変更します。

```shell-session
$ heroku config:set RACK_ENV=staging RAILS_ENV=staging
```

これで、ステージング用のHerokuアプリにpushしたら、stagingブランチの内容が適応されるようになりました。

最後に、Railsアプリの設定もstagingに対応させてあげましょう。

```yaml:config/database.yml
# 追加　
staging:
  adapter: mysql2
  encoding: utf8
  database: latte-art_production
  pool: 5
  username: root
  password:
  socket: /tmp/mysql.sock
```

```rb:config/environments/staging.rb
SampleApp::Application.configure do
  # 環境設定を色々
  # 基本的にproductionと同じでよい
  # ただし、環境変数などはstaging用に設定します

  # 例えばRedisのURLを設定するときはproductionと別のものをstagingで用意するので、staging用のredisのURLを設定します
  ENV["REDISTOGO_URL"] = 'xxxxxxx-xxxxxxx'
end
```

以上でステージング環境の設定は終了です。

## 4. 継続的インテグレーション (CI: Countinuous Integration)の環境設定
<br>
> このセクションでは、Githubにpushしたら自動的にHerokuにGithubのコードがデプロイされるように設定する方法を説明します。

<br>

stagingとmasterブランチをherokuとgitに設定しましたが、毎回GithubとHerokuにpushするのは大変です。

さらに、herokuにpushしても、以下のコマンドを実行しないとデータベースが展開されないので、コマンドを打つまでの間はサーバーが停止状態になってしまいます。

```shell-session
$ heroku run rake db:migrate --app [HEROKU_APP_NAME]
```

そこで、 **Githubにpushされたら、自動的にHerokuにもpushしてrake db:migrateまでしてくれるサービス** を利用してみましょう。

このようなデプロイを自動化することを、 **継続的インテグレーション(CI)** といいます。

私が使ってるCIのサービスでオススメなのが、「 **Codeship** 」です。

![codeship](http://pioneers.io/wp-content/uploads/2013/09/logo_codeship_colour.png)

Codeshipは、Herokuのアドオンとしても提供されており、Githubにpushすると自動的にHerokuにデプロイしてくれます。

さらに、さきほど作成したstagingやmasterブランチをpushすると、どのブランチがpushされたか自動で認識し、ブランチ毎に別々のHerokuアプリにデプロイしてくれます。

このCodeshipの設定も長くなるため、[別の記事にまとめました。](http://qiita.com/u651601f/items/8da10ca147be241318b3)
こちらの記事を参考に設定してください。


設定が終われば、SourceTreeで stagingにpush -> [STAGING_APP_NAME]に、masterにpush -> [HEROKU_APP_NAME]に自動的に適応されるようになると思います。


> 長くなりましたので、最後に開発の流れをおさらいします。
>
> 1. developブランチで開発、commit & push
> 2. stagingブランチから developをpull & push
> 3. stagingで動作確認ができたら、masterブランチから stagingをpull & push
>
> あとは待ってるだけで自動的にHerokuにデプロイされます。

## 5. モニタリングツールの導入
<br>
> このセクションでは、運営時にHerokuのサーバーを監視するサービスの導入方法を説明します。

<br>

最後に、運営時に必要となるであろうツールの導入方法を紹介します。

ステージングや本番環境で上手く動作しているように見えても、実際に長期運営していると、思いもよらない不具合が発生することは必ずあります。

従って、日頃からモニタリングツールを使用して、アプリケーションの動作を監視し、不具合が発生すればすぐに原因を突き止めて改善していく必要があります。

私が特におすすめするモニタリングサービスは、 **「New Relic, Papertrail, Rollbar」** です。

#### 1. New Relic

![new relic](http://www.beseen-marketing.co.uk/wp-content/uploads/2014/02/newrelic_logo.png)

New Relicを使えば、毎日どのくらいのユーザーがアクセスしているのか、エラーが発生した時間帯はいつ頃か、などの総合的な監視が出来ます。

機能はかなり豊富なので、この記事では紹介しきれませんが、とりあえず導入方法を説明するので是非使ってみてください。

まずは、HerokuにNew Relicのアドオンを追加します　

```shell-session
$ heroku add ons:add newrelic --app [HEROKU_APP_NAME]
```

Herokuのダッシュボードにアクセスすると、アプリにアドオンが追加されているのが確認できます。

![Resources___latte-art.png](https://qiita-image-store.s3.amazonaws.com/0/25585/88c95b8b-b7e7-0638-d882-d5d7f31e6c06.png)

New Relicのアドオンをクリックすると、New Relicのサイトまでアクセス出来ます。

すると、数段階でNew Relicを設定する方法のページが出てくるので、ナビゲーションに従って設定してください。
(確か、環境の選択 -> keyの作成 -> yamlファイルのダウンロード -> Railsのフォルダに設置 -> Railsデプロイ って流れで設定できるはず)

あとは、数分待ってNew Relicにアクセスすると、PV数などのグラフが表示されていることが確認できます。　

#### 2. Papertrail
![papertrail](http://blog.papertrailapp.com/images/header.png)

papertrailは、ログ情報を一定期間保存してくれるサービスです。New Relicだけではどうしてもわかりにくい不具合が発生した時は、papertrailのログ情報を見てあげると、解決策が見えてくるかもしれません。

また、大量のログを手作業で確認するのは大変なので、日付などを検索して、必要なログを見つけることも出来ます。

アドオンの導入方法は今までと同じで、設定自体も特にすることが無いので、Papertrailについては自分で触りながら試してみてください

```shell-session
$ heroku addons:add papertrail --app [HEROKU_APP_NAME]
```


#### 3. Rollbar
![rollbar](https://s3.amazonaws.com/photos.angel.co/startups/i/116055-eb9feeae274ff9322098ea56498e6303-medium_jpg.jpg?buster=1361913126)

ここまで2つのモニタリングツールを紹介しましたが、不具合が起こった時にすぐに気づくためには通知してもらわないといけません。

Rollbarは、Herokuで不具合が発生して、サーバーがダウンしたりした時に、メール等で通知してくれるサービスです。

デフォルトの設定では、Herokuに登録されたメールアドレスに通費が来るはずです。

アドオンの導入は、これまでと同じです。

```shell-session
$ heroku addons:add roll bar --app [HEROKU_APP_NAME]
```


## 最後に
いかがだったでしょうか？
ここで紹介したアドオンやサービスは、基本的にすべて無料で使用することが出来ます。従って、これからRailsを使ってWebサービスを作る際には、いきなりAWSに手を出さずに一度Herokuを使ってサービスを運営してみるのもいろしいかと思います。

誤字・誤謬、もっとよい方法論等があれば参考にさせていただきたいので、コメントよろしくお願いします。