Railsチュートリアル 第7章 ユーザー登録 - プロのデプロイ

# 前提条件

これまで何度か本番環境へのデプロイを行ってきました。しかしながら、「RDBMSへのアクセスが発生するアプリケーションの本番環境へのデプロイ」は、今回が初めてです。「RDBMSにアクセスする」となると、本番環境へのデプロイにも、これまでとは違うレベルの配慮が求められることになります。

# 本番環境でのSSL

## SSLの必要性

Railsチュートリアル第7章、今回開発したユーザー登録フォームで本番環境にデータを送信すると、名前やメールアドレス、パスワードといったデータがネットワーク越しに流れていきます。これらの通信内容は、途中で捕捉することが可能です。しかもデフォルトでは通信内容が暗号化されていません。「暗号化されていない通信内容を途中で捕捉できる」というのは、例えば名前やメールアドレスといった情報を容易に盗むことができてしまうということです。

というわけで、ネットワーク上を流れていく情報の安全を確保するため、「クライアントとサーバーの間で通信内容を暗号化する」という技術を導入する必要が出てきます。SSLというのは、そうした技術の中でも主流となっている技術です。HTTPの通信に対してSSLを適用したものは、特にHTTPSと呼ばれます。

とりわけ昨今では、「不特定多数のユーザーが使用する前提のもと、利便性を優先してあえて通信の暗号化を行わない」という公衆無線LANが世界各所で運用されるようになっています。そうした環境が当たり前に存在することを前提とするならば、「実際に使用する通信経路に関係なく、クライアントとサーバーの間で通信内容を暗号化する」という技術、例えばSSLの必要性は非常に高いものとなります。

## RailsとSSL

今回SSLを実装するのは、まずユーザー登録ページのみが対象です。しかしながら、Railsにおいては、Webサイト全体に対してSSLを適用することも容易に可能なようになっています。例えば、「ログイン機構をセキュアにする」「セッションハイジャックの脆弱性に対処する」といった目的に対しても、「SSLの採用」という解決を容易に実現することができるのです。

SSLの有効化も容易に可能です。`config/environments/production.rb`という、本番環境に適用する設定を記述するRubyコードを1行変更するだけです。この設定により、SSLが有効になるだけではなく、ユーザーに対してSSLの使用を強制するようにもなります。

```diff:config/environments/production.rb
  Rails.application.configure do
    ...略
    # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
-   # config.force_ssl = true
+   config.force_ssl = true
    ...略
  end
```

## HerokuにおけるSSL

Herokuでは、デフォルトの状態でSSLを使用することが可能です。しかしながら、SSLの使用をWebブラウザに強制することはしていません。例えば、現時点で本番環境上にデプロイされているRailsチュートリアルのサンプルアプリケーション（第6章終了時点のもののはずです）のURLのうち、`https://`を`http://`に変えても、サンプルアプリケーションのWebサイトにアクセスすることができてしまいます。

httpsスキームではなくhttpスキームでWebサイトにアクセスすると、その通信は安全ではなくなってしまいます。

Heroku上のRailsアプリケーションにおいて、ユーザーに対してSSLの使用を強制させるには、上述「RailsとSSL」項に記載の通り、Rails側で所定の設定を行う必要があります。

## SSLそのもののセットアップ

SSLそのもののセットアップには、本来、「ドメイン毎にSSL証明書を購入し、その他多くの作業を行う」必要があります。しかしながら、Herokuにおいては、Herokuのサブドメインを用いるのであれば、Heroku側でセットアップされたSSL環境を使用することが可能です。この場合、SSL証明書もHeroku側が用意しています。

一方、独自サブドメインを使用する場合は、SSL証明書を購入し、「購入した証明書をHerokuにセットアップする」という作業が必要となります。

# 本番環境用のWebサーバー

Railsチュートリアルでは「Webサーバー」という見出しになっていますが、Webサーバーというよりは、アプリケーションサーバーに関する話です。

## WEBrickとPuma

Herokuのデフォルトでは、WEBrickというアプリケーションサーバープログラムを使用する設定になっています。WEBrickは環境設定や実装が容易である反面、著しく大量のトラフィックを扱うには不向きな実装となっています。すなわち、WEBrickは本番環境のサーバープログラムとしては不適切であるということです。

そこで、より本番環境向きのアプリケーションサーバープログラムであるPumaを使用するようにHerokuをセットアップする必要があります。必要なプロセスとしては以下のとおりです。

1. puma gemを`Gemfile`に追加する
2. Heroku上でPumaプロセスを実行するために、`Procfile`という設定ファイルを追加する

上述手順の注意点は以下です。

* Rails 5では、デフォルト設定でPumaが使用可能である
* `Procfile`は、Railsアプリケーションのルートディレクトリ（`Gemfile`があるのと同じディレクトリ）に置いておく必要がある

`Procfile`の内容は以下の通りになります。

```./Procfile
web: bundle exec puma -C config/puma.rb
```

## 余談 - PHPにおけるアプリケーションサーバー

ちなみに、Webアプリケーションの開発言語がPHPである場合、Webサーバープログラムとアプリケーションサーバープログラムを別にセットアップするのは一般的ではありません。PHP環境においては、ApacheしかりNginxしかり、「WebサーバープログラムにPHPのアプリケーションサーバー機能が実装されている」というのが一般的であるからです。

# 本番環境へのデプロイ

## 実際のデプロイ操作

まずは開発環境にて、`rails test`が通ることを確認します。

```:（開発環境）
# rails test
Running via Spring preloader in process 352
Started with run options --seed 32564

  21/21: [=================================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.41443s
21 tests, 50 assertions, 0 failures, 0 errors, 0 skips
```

テストが通ることが確認できたら、ソースコードがある環境から次の手順を実行します。

```:（ソース環境）
>>> git add -A
>>> git commit -m "Use SSL and the Puma webserver in production"
>>> git push
>>> git push heroku
>>> heroku run rails db:migrate
```

ここでは、以下の手順を実施しています。

1. Git…ここまでの変更をステージング
2. Git…コミットメッセージを付けた上でコミット
3. Git…GitHubリポジトリにプッシュ
4. Git…Herokuにデプロイ
5. Heroku…データベースのマイグレーション処理

# 演習 - プロのデプロイ

## 1. ブラウザから本番環境 (Heroku) にアクセスし、SSLの鍵マークがかかっているか、URLが`https`になっているかどうかを確認してみましょう。 

<img width="1178" alt="スクリーンショット 2019-10-25 19.37.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/06e2d855-c116-7184-276f-edfab9291721.png">

サンプルアプリケーションのトップページが無事表示されました。URLの前に緑色の鍵マークが表示されています。URLもきちんと`https://`から始まっています。

## 2. 本番環境でユーザーを作成してみましょう。Gravatarの画像は正しく表示されているでしょうか? 

「Sign up now!」というボタンをクリックしてみます。

<img width="1178" alt="スクリーンショット 2019-10-25 19.38.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/66e2e7ce-dae3-bd98-5883-593df125c715.png">

ユーザー登録フォームが表示されました。

<img width="1178" alt="スクリーンショット 2019-10-25 19.42.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/4de03186-b1a9-f901-780c-07bd3429fc8d.png">

ユーザー登録も無事完了しました！Grabatarの画像もきちんと表示されています。