[Ruby] RailsをHerokuへデプロイする時の７つの注意事項 [Heroku]

先日、[Ruby開発者のためのHeroku入門](https://developer.salesforce.com/events/webinars/heroku_ruby_0124)というWebセミナーを行いました。この時の内容の振り返りとしての、注意事項の補足説明です。

元のスライドは[Ruby開発者のためのHeroku入門](http://www.slideshare.net/DeveloperForceJapan/rubyheroku)を御覧ください

# デプロイ前の注意事項

デプロイする前、アプリケーションを開発する時に考慮しておくべき事項 5つを紹介します

## 1. データベースサーバの選定について

Heroku では、RDBMS は [Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql)を、高速なKVSの場合には [Heroku Redis](https://elements.heroku.com/addons/heroku-redis)を推奨することが一般的です。純粋に、Herokuが提供しているアドオンだからということと、[Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql)に限っては、常に最新版を利用することができることも、推奨するポイントです。

もちろん、MySQL や Mongo、Cassandraなど、3rd Vendorの提供するデータベースを利用することも可能ですが、Herokuに最適化されているものとしては、頭に「Heroku」のつくアドオンを推奨します。先頭に「Heroku」とついているものは、`Heroku`の提供しているアドオンであることを示しています。

また、[SQLite](https://devcenter.heroku.com/articles/sqlite3)の利用は推奨していません。これは、Heroku Dynoが、約24時間おきに Restartする仕様に従い、ローカルのディスクも初期化されてしまうためです。

## 2. config/database.yml

[Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql)だけに限りませんが、データベースとの接続定義は、通常は環境変数に定義されます。Rails でデータベースを利用する場合には、この接続定義を利用することでかんたんに接続できます。

例えば、[Heroku Postgres](https://elements.heroku.com/addons/heroku-postgresql)を利用する場合には、次のように記述します。

```bash:database.yml
production:
  url: <%= ENV['DATABASE_URL'] %>
```

## 3. Procfile

Herokuは、deployされたときのファイルの構成や、内容に従って、概ね自動的に最適な構成を選択して、適用します。Ruby の場合、`Rails`や`Rack`仕様の Webアプリは即座に検知され、一般的な起動手順や環境変数が自動的に定義されます。

しかし、通常とはちがう起動方法を選択したい場合(Webrickではなく、Thin が使いたいとか)や、Web Dyno以外の Worker Dynoの起動手順を設定したい場合には、`Procfile` を定義します。

通常の `Rails`を起動する場合の `Procfile`。この場合であれば、`Procfile`を準備しなくても、`Heroku`で自動的に実行してくれます。

```bash:Procfile
web: bundle exec rails server -p $PORT -e $RAILS_ENV
```

通常とは異なる起動手順や、Worker Dynoの起動手順を指定したい場合

```bash:Procfile web: bundle exec ruby app.rb
mqtt: bin/proximo bundle exec ruby mqtt.rb
redshift: bin/proximo bundle exec ruby redshift.rb
```

この場合だと、Web サーバは `app.rb` によって起動されます。`mqtt`と`redshift`という Worker Dynoが準備されていて、Web Dynoとは別に、非同期で実行されます。また、`bin/proximo` は Proximo アドオンを利用して、IPアドレスを固定化して利用しています。このように、固有の起動手順を利用する場合には、`Procfile` は必須になります。

参考 [外部接続時に固定IP化する2つの方法](http://qiita.com/sho7650/items/872b5757e250d4b3eb95)

## 4. Gemfile (Rails4の場合)

呪文のように覚えておきましょう。

Herokuで`Rails`を利用する場合には、`Production` 用に `rails_12factor` Gem を利用するように定義してください。

```ruby:Gemfile
group :production do
  # Use postgresql as the database for Active Record
  gem 'pg', '~> 0.15'
  # Use easily Heroku with Rails
  gem 'rails_12factor'
end
```

※ Rails5 からは、不要になりました

## 5. config/secret.yml

たまに、`.gitignore` で、`config/secret.yml` が git の対象にならないように指定されている時があります。もし、`.gitignore` 内に `/config/secret.yml` が定義されていたら、注釈するか消しましょう。

通常、次のように標準で定義されているはずですので、そのままにしておきます。Heroku側では、`Rails`と判断した場合、自動的に `SECRET_KEY_BASE` 環境変数を生成する仕組みになっています。

```ruby:config/secret.yml
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
```

# デプロイ時の注意事項

デプロイする時に、忘れずに実施しておきたい二つの注意事項について、ご説明します。

## 1. Gemfile.lock が必須

どこからか `git clone` してきた場合には、ほぼ必要ないと思われますが、自作の Webアプリケーションをデプロイする場合には、`Gemfile.lock` が必須となります。

したがって、Linux/Mac など UNIX環境が必要になると思われます(Windowsでのやり方あったら教えてください)。Heroku はデプロイされたときに、`Gemfile.lock`に従って Rubygems を登録しているようです。

Herokuがデプロイ時に実施している `bundle install` でのディレクトリ指定は次のようになっています、参考にどうぞ。

```bash:bundle_install
bundle install --path vendor/bundle --binstubs vendor/bundle/bin
```

## 2. db の migrateも必要

自動的に実施してくれていたことがあった気がしますが、今日現在は、手動でのマイグレーションが必須です。Heroku へデプロイした直後に、次のように Heroku上で `db:migrate` を実行しないと、データベースのテーブルがないまま、エラーを吐き続けることになります。

```bash:rake_db:migrate
heroku run bundle exec rake db:migrate
```

# その他

Heroku、および Heroku Dyno は、アプリケーションを最適化して実行する上で、必要最小限の制約があります。

詳細は、[Limits](https://devcenter.heroku.com/articles/limits)をご覧ください