Railsチュートリアル 第1章 - Herokuへのデプロイ

Railsチュートリアル本文同様、本番環境としてはHerokuを使って進めていきたいとおもいます。それではスタート。

# `Gemfile`の内容を変更し、`Gemfile.lock`に変更を反映する

HerokuではPostgreSQLデータベースを用いるため、本番環境に`pg`というgemをインストールする必要があります。そのための設定を`Gemfile`に書き込みます。

```diff:Gemfile
...略
group :development do
   gem 'spring',                '2.0.2'
   gem 'spring-watcher-listen', '2.0.1'
 end
+
+group :production do
+  gem 'pg', '0.20.0'
+end
```

Railsの開発環境（私はDockerで構築しました）の中に入り、`Gemfile.lock`を更新するために`bundle install`を実行します。本番環境でしか使わないGemをインストール対象から除外するため、`--without production`というオプションを付けています。

```:bash
# pwd
/var/www/hello_app

# bundle install --without production
Fetching gem metadata from https://rubygems.org/............
...略
Bundle complete! 15 Gemfile dependencies, 64 gems now installed.
Gems in the group production were not installed.
Bundled gems are installed into `/usr/local/bundle`
```

`Gemfile.lock`の更新は問題なく終わったようです。「productionグループはインストール対象から除外された」というのも、想定通りの動作です。

おっと、ここまでの変更内容をGitにコミットするのも忘れずに。

```:zsh
>>> git commit -a -m "Update Gemfile for Heroku"
```

# Herokuへの接続

まず、`heroku --version`というコマンドにより、Herokuコマンドラインクライアントがシステムにインストールされているかどうかを調べます。

```:zsh
>>> heroku --version
heroku/7.26.2 darwin-x64 node-v11.14.0
```

おっと、私が使っているMacBook Airには、既にHerokuコマンドラインクライアントがインストールされていたようですね。というわけで、早速HerokuにログインしてSSH鍵をアップロードしましょう。

```:zsh
>>> heroku login --interactive
...略
Logged in as {登録メールアドレス}

>>> heroku keys:add ~/.ssh/id_rsa_for_heroku.pub
...略
```

`heroku login --interactive`コマンドを実行すると、シェル上で登録メールアドレスとパスワードの入力を求められます。

`heroku keys:add`コマンドで、HerokuにSSH鍵を追加することができます。デフォルトでは`~/.ssh/id_rsa.pub`を公開鍵として使用しますが、上記のように明示的に公開鍵を指定することもできます。

## HerokuへのSSH接続のために`~/.ssh/config`の内容を変更する

HerokuへのSSH接続に標準以外の設定を用いる場合、`~/.ssh/config`の内容を変更する必要があります。下記の例は、秘密鍵として`~/.ssh/id_rsa_for_heroku`を用いるように設定しています。[herokuの公開鍵登録と、そのリセット方法 - えんたつの記録](http://blog.livedoor.jp/tattyamm/archives/4644279.html)を参考にさせていただきました。

```:~/.ssh/config
Host heroku
  User git
  HostName heroku.com
  IdentityFile    ~/.ssh/id_rsa_for_heroku
  Port 22
  TCPKeepAlive yes
  IdentitiesOnly yes
```

# サンプルアプリケーション実行場所の確保と、実際のデプロイ

SSH鍵のアップロード完了後、`heroku create`コマンドを実行すれば、Herokuサーバーにサンプルアプリケーションの実行場所が作成されます。

```:zsh
>>> heroku create
Creating app... done, ⬢ fast-spire-53098
https://fast-spire-53098.herokuapp.com/ | https://git.heroku.com/fast-spire-53098.git
```

GitリポジトリのURLが書かれていますね。書かれているGitのリモートリポジトリに、ローカルリポジトリプッシュすればデプロイ完了！というわけなのです。早速デプロイしてみましょう、ということだったのですが…

```:zsh
>>> cd ~/docker/rails_tutorial_test/hello_app

>>> git push heroku master
fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

`heroku`というリモートリポジトリは見つからない、という意味のエラーメッセージですね。先程`heroku create`で生成されたGitのリモートリポジトリを、herokuという名前で登録する必要があります。というわけで、`git remote add`コマンドを実行します。

```:zsh
>>> git remote add heroku https://git.heroku.com/fast-spire-53098.git
```

再び`git push`します。

```:zsh
git push heroku master
Enumerating objects: 127, done.
...略
remote: Verifying deploy... done.
To https://git.heroku.com/fast-spire-53098.git
 * [new branch]      master -> master
```

ローカルリポジトリの`master`ブランチの内容が、リモートリポジトリの`heroku/master`ブランチに反映されました。

本当にこれでWWW上にRailsアプリケーションがデプロイされたのでしょうか？というわけで、実際にアクセスしてみます。先程生成されたサンプルアプリケーションの実行場所は、https://fast-spire-53098.herokuapp.com/ というURLでした。すると、以下の画面が出てきました。

<img width="866" alt="スクリーンショット 2019-07-29 15.51.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/7b31d71b-adf1-9dd0-9103-2a3be73accf8.png">

goodbye, world!と表示されています。…そういえば、[Hello, world!の後の演習](https://railstutorial.jp/chapters/beginning?version=5.1#sec-exercises_hello_world)が全て終わった状態のアプリケーションをデプロイしたのでしたね。

**なんということでしょう。** これでRailsアプリケーションが一つWWW上に公開されたのです！

# 演習

## 2. 1.3.4.1と同様、ルートへのルーティングを変更してgoodbyeアクションの結果が表示されるようにしてください。またデプロイ時には、Git pushのmasterをあえて省略し、git push herokuでデプロイできることを確認してみてください。 

前述の通り、先にgoodbyeの結果が表示される状態でデプロイしてしまったので、逆にhelloの結果が表示されるようにしてデプロイしてみます。一コミットで二つのファイルを一度に変更したため、diffの中身も2つのファイルに対するものそれぞれが存在します。

```diff:
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 365da42..f543e7c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base
   protect_from_forgery with: :exception
 
   def hello
-    render html: "¡hola, mundo!"
+    render html: "hello, world!"
   end
 
   def goodbye
diff --git a/config/routes.rb b/config/routes.rb
index 4ddfae8..3f94e71 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,3 +1,3 @@
 Rails.application.routes.draw do
-  root 'application#goodbye'
+  root 'application#hello'
 end
```

ローカルリポジトリの変更をGitHub側のリモートリポジトリにプッシュします。

```:zsh
>>> git push origin master
Enumerating objects: 13, done.
．．．略
remote: 
To github.com:rapidliner0/hello_app.git
   a11b590..2822f13  master -> master
```

ローカルリポジトリの変更をHeroku側のリモートリポジトリにプッシュします。

```:zsh
>>> git push heroku master
Enumerating objects: 13, done.
...略
To https://git.heroku.com/fast-spire-53098.git
   a11b590..2822f13  master -> master
```

ここまで終わった時点での https://fast-spire-53098.herokuapp.com/ のスクリーンショットが以下のとおりです。

<img width="866" alt="スクリーンショット 2019-07-29 17.44.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/0e305eea-5780-c87a-69b1-5e592dee5db5.png">

期待通りの出力がされています。

## 1. 1.3.4.1と同じ変更を行い、本番アプリでも「hola, mundo!」を表示できるようにしてください。 

上記演習2.終了時点からの続きです。

まず、`app/controllers/application_controller.rb`に、以下の変更を行います。

```diff:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   protect_from_forgery with: :exception
 
   def hello
-    render html: "hello, world!"
+    render html: "hola, mundo!"
   end
 
   def goodbye
...略
```

ローカルリポジトリの変更をGitHub側のリモートリポジトリにプッシュします。

```:zsh
>>> git push origin master
Enumerating objects: 13, done.
．．．略
remote: 
To github.com:rapidliner0/hello_app.git
   2822f13..c5d8e63  master -> master
```

ローカルリポジトリの変更をHeroku側のリモートリポジトリにプッシュします。

```:zsh
>>> git push heroku master
Enumerating objects: 13, done.
...略
To https://git.heroku.com/fast-spire-53098.git
   2822f13..c5d8e63  master -> master
```

ここまで終わった時点での https://fast-spire-53098.herokuapp.com/ のスクリーンショットが以下のとおりです。

<img width="866" alt="スクリーンショット 2019-07-29 17.56.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/ed05d46a-798f-a887-5bf0-4978ceca174b.png">

期待通りの出力がされています。