【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】


# herokuを使ったRailsアプリのデプロイ
Railsといえば「爆速でアプリが作れる」だと思いますが、そうやって作ったアプリもやっぱり「爆速でデプロイしたい」ですよね。
そんな時に非常に便利になってくるのがherokuというサービスなのですが、プログラミングの講師をさせていただいている時、生徒さんにherokuにデプロイしてもらってもうまくいかないことが多いです。

インターネット上にherokuによるデプロイの記事は数多に存在しておりますが、なぜそのようなことがおきてしまうのか？

それは、簡単にデプロイできすぎてしまうため、__エラーが起きるときの原因と結果が知られていない__からかと思われます。
すごい人はすぐ解決しちゃうし、初心者の方は解決するので精一杯なのでアウトプットするまでに至らない、といったようなことかなと。

なので、チュートリアル形式で__エラーをなるべく起こさないように__Railsアプリをherokuにデプロイして行きます。


## 必要なもの、コト(ここら辺もチュートリアル形式でやっていきます)
- デプロイしたいRailsアプリ
- gitのインストール
- herokuのユーザー登録
- heroku-cliのインストール

## 自分の環境
- Rails 5.1.6
- Ruby 2.3.1
- git 2.14.1
- heroku-cli/6.15.37-14485d4 (darwin-x64) node-v9.9.0

## 始める前に

Railsアプリの作成については省略したいところなのですが、
もしherokuへのデプロイのみを試したい、という方がいればアプリの作成できる環境にはいり、ターミナルで以下のコマンドを打ってください。
(#~ となっているのはコメントアウトなので、無視してください。)

```console:ターミナル
$rails new heroku_app #アプリ名はなんでも良いです
$cd heroku_app #作ったアプリに移動します
$rails g scaffold blog title:string body:text #scaffoldで作っていますがなんでも良いです
$rake db:migrate
```
これで、blogモデル、blogsコントローラなどなど色々作られた簡易的なブログができたと思います。Railsはやはり爆速ですね！はい。

確認のため、サーバーを立ち上げてみましょう。ターミナルで打ってください。

```console:ターミナル
$rails s
```

以下のURLを押してみてください。Railsのwelcomeページが表示されていたらOKです！
http://localhost:3000

<img width="756" alt="スクリーンショット 2018-05-21 13.06.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/6b282b41-2b2f-b369-6291-7558fd33d21e.png">


では次に進んで行きましょう！

## はじめに

早速デプロイ・・・とはいきたいところなんですが、まず初めにRailsアプリをherokuにあげれるよう準備してあげなくてはなりません。

### Railsアプリをデプロイする準備
大きく分けて以下の変更を行います。全てRailsアプリの設定の変更です。

- config/routes.rbの設定
- Gemfileの設定
- config/datebase.ymlの設定
- config/environments/production.rbの設定
- bin以下のフォルダの設定(任意)

そんなに難しくありませんので、順番にやっていきましょう！

#### config/routes.rbの設定

configフォルダの中のroutes.rbを以下のように編集してください。トップページをindexに設定しています。
__もちろん、ご自身のアプリの設定したいトップページをここに定義してください。__
大事なのは__トップページを何かしらに設定していること__です。

```ruby:config/routes.rb
Rails.application.routes.draw do
   resources :blogs
   root 'blogs#index' #トップページをblogsコントローラのindexアクションに設定
 end
```

これをしないと本番環境(デプロイした後の環境)で「urlが正しく有りません」というエラーになってしまいます。
先ほどアクセスした
http://localhost:3000
にアクセスして、ご自身の設定したトップページが表示されていればOKです。
先ほどscaffoldで作成したアプリの場合は、このようになります。

<img width="472" alt="スクリーンショット 2018-05-21 13.04.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/383e77dc-1b2a-264b-377f-60fb5ae8f18c.png">

#### Gemfileの設定

次に、Gemfileを変更していきます。
まず、gem 'sqlite3'と、書いてある箇所があると思うのですが、それをコメントアウトしましょう。文字列の先頭に#をつけます。

```Ruby:Gemfile
# sqlite3
```

コメントアウトができたら、またGemfileの`group :development, :test do ~~ end`__内に__以下のように書き込んでください。下の方にあります。

```Ruby:Gemfile
group :development, :test do
  gem 'sqlite3' #do ~ end内部に追加。他のgemは残してください。
end
```

他にも`byebug`や`capybara`など色々なgemが書いてあったと思いますが、気にせずで問題ありません（消しちゃダメですよ！）。`do ~ end`内でしたらどこでも大丈夫です。

最後にもう一つだけGemfileに追加します。以下の記述を__そのまま__Gemfileのどこかに追加してください。ごちゃごちゃにならないよう、一番最後に記述すると良いかもしれません。

```ruby:Gemfile
group :production do
  gem 'pg'
end
```

ここでは__環境ごとのデータベースの変更__を行なっています。
開発していた時(developmentやtest環境)はRailsアプリに最初からついている__SQLite3__というのを使っていたのですが、本番環境(production)、もとい__これからデプロイする予定であるheroku__では__PostgreSQL__(略してpg)というデータベースが最初からインストールされているので、その環境に合うようにこのような変更をしています。 
SQLite - https://www.sqlite.org/index.html
PostgreSQL - https://www.postgresql.org/

さて、Gemfileを変更したので忘れずにbundle installをしておきましょう。ただし、以下のようにオプションを指定します。

```console:ターミナル
$bundle install --without production
```

このオプションをつけることによって、__group :produciton do~end内以外の__gemをインストールすることができます。
自分のパソコンにはPostgreSQLは入っていないため、このようなオプションをつけています。

ちなみに、このオプションは一度打ち込めば、アプリ内部の`/bundle/config`というところに書き込まれるため、それ以降は`--without produciton`を打たなくても本番環境以外のgemをインストールしてくれるようになります。その他の__bundle install時のオプションは全てここに書き込まれます。__

.のついているファイルは隠しフォルダといい通常は見れないのですが、ターミナルで`ls -a`とうてば確認することができます。(-aは隠しフォルダを表示するコマンドです。)

```ruby:.bundle/config
#このようになっていたらOKです
BUNDLE_WITHOUT: "production"
```

もし無くしたければ、config内の記述を削除してしまってください。

さて、gem周りの設定は終わりましたが、データベースの変更にはもう一ついじらなくてはいけない箇所があります。__config/database.yml__です。

#### config/datebase.ymlの設定

さきほどGemfileを変更したことにより__このアプリは本番環境でPostgreSQLを使います__、という宣言（と機能をインストールするための準備）は完了したのですが、実際にデータベースと接続する記述はまだ完了していません。その接続の設定をする箇所がconfigフォルダの中にある__database.yml__というファイルです。

ファイル内の下の方にある__production__環境についての設定を、以下のように変更してください。

注意して欲しいのが、production:以降の記述は必ずインデント、もとい__半角スペース２個ぶん__の空白を開けて記述してください。.ymlという拡張子のファイルは__インデントで記述を判別__しています。

```yml:config/database.yml
production:
#半角スペース２個分の空白を開ける
  <<: *default
  adapter: postgresql
  encoding: unicode
  pool: 5
```

adapter: postgresql - postgreSQLのデータベースに接続します。
encoding: unicode - unicodeという文字コードを使用します。
pool: 5 - DBに接続できる上限の数を決めます。今回は5。

さて、これにより本番環境でPostgreSQLと接続する準備ができました。ここまでくればRailsアプリの設定はほぼ完了しています。

あとは初心者がエラーを起こしがちな箇所への対策を行なっていきたいと思います。

#### config/environments/production.rbの設定

実は、Railsは__本番環境での動的な画像の表示(というかプリコンパイル)がデフォルトでオフになっています。__
~~画像を表示するために以下の記述を`false`から`true`に変更してください。（自分は31行目にありました）~~
この記述により、__assets以下のフォルダから動的にコンパイルしながらページを読み込みます。__

```ruby:config/environments/production.rb
#デフォルトでfalseとなっている以下の箇所をtrueに変更
  config.assets.compile = true
```

こちらの記述はパフォーマンスを悪化させる原因となりますので、こちらを参考にするのが良いです。(@jnchito さんありがとうございます。)
https://qiita.com/jnchito/items/3d225112a3ac95379b1d~~

これが終わればいよいよ次でRailsの設定は最後です。

#### bin以下のフォルダの設定

この設定は人によっては大丈夫なことも多いのですが、rbenvなどを使ってない人は陥りがちなことが多いので一応記述しておきます。

後述するのですが、データベース周りの設定は完璧なのに__heroku run rails db:migrate__が通らない人はここの箇所で詰まっている人が多いです。

アプリ内に`bin`というフォルダがあるのですが、その中のファイル全て(bundle,rails,rake,setup,spring,	update,yarn)の一番上に

```ruby
#!/usr/bin/env ruby
```

という記述があると思います。ここの記述が、

```ruby
#!/usr/bin/env ruby 2.3.1
```

など__バージョン指定されてしまっているファイル__全てのバージョンを削除してください。つまり、上の記述から

```ruby
#!/usr/bin/env ruby
```
このように__数字を削除__するということになります。(今回は2.3.1の部分)

さて、長くなってしまいましたがこれでRailsアプリの設定は終了になります。本格的にデプロイに移っていきましょう。


herokuのデプロイには__git__というツールを使用します。

## git とは
- 保存するためのツール。めちゃ多機能。過去や、並行世界とかにいける。

ここではgitについての詳しい解説は行いません。以下のページで勉強してみましょう。
https://qiita.com/yunico-jp/items/87bdd13971e82833f6bb

以下のurlからインストールしましょう。
https://git-scm.com/downloads
(macかwindowsかお間違えなく！)
vagrantの方は「Linux/Unix」を選択し、自分のOSにあったコマンドを打てばOKです。
https://git-scm.com/download/linux
### Debian/ubuntuの場合
```console:ターミナル(ubuntu内)
$apt-get install git
```
以下のコマンドを打って、インストールしたバージョンが出てきたらインストールが成功しています。

```console:ターミナル
$git --version
>>git version 2.14.1
```

gitがインストールできたら、ターミナルで以下のコマンドを打ってください。

このコマンドで、「このアプリでgitを使います」という指示を出しています。

### 最初の一回だけ！

```console:ターミナル
$git init   #このフォルダをgitと紐づけます、という指示。
```

続けて、gitを使ったアプリを保存するコマンドです。

### 変更したら毎回やるやつ

```console:ターミナル
$git add -A #保存するファイルの選択。-Aは全部
$git commit -m "first commit" #addしたファイルの保存の確定
```

ここで、初めてコミットする場合は、githubのユーザー名とemailの入力を求められます。
githubに登録していない方は無視してしまって大丈夫です。もしくは、登録する予定のメアドとユーザーネームを入力してください（笑）
### 初めてgitを使ってコミットした方

```console:ターミナル
$git config --global user.email #ギットハブに登録したemail
$git config --global user.name #ギットハブに登録したユーザーネーム
```
念のためもう一度commitしましょう。


```console:ターミナル
$git commit -m "first commit"
```
以下のように
<img width="592" alt="スクリーンショット 2018-05-18 21.48.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/9a10b10c-2438-53f3-6bb0-5aaaa1f0536b.png">
と、create mode ...とたくさん出てきた方か、
<img width="522" alt="スクリーンショット 2018-05-18 21.48.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/2611a1d4-109c-2ef0-533f-f1bbc2e17ad0.png">
このようにnothing to commitと出てきた方は大丈夫です。

では、いよいよherokuを使っていきます。

## herokuとは
- PaaS（Platform as a Service）と呼ばれるサービス
- サーバやOS、データベースなどの「プラットフォーム」と呼ばれる部分を、インターネット越しに使えるようにしてくれるサービス
- 簡単かつ無料でRailsアプリがあげられる

通常、Railsアプリはデプロイが難しいことが多いのですが、このherokuを使うと比較的簡単にデプロイすることができます。機能的には物足りない部分もあるのですが、その場合は有料版を使えば問題なくサービスを立ち上げることができます。

### herokuへの登録

さて、gitの準備はできましたので、herokuに登録しましょう。英語ですが、google翻訳を駆使すれば全然問題ありません。(僕も英語できないんです)

https://signup.heroku.com/login

会員登録が完了したら、今度はherokuの機能を自分のPCに紐付けましょう。cliをダウンロードします。

https://devcenter.heroku.com/articles/heroku-cli

今回もmacかwindowsか、それとも他のか注意してください。
サイトにも書いてありますが、ubuntuの場合は以下のコマンドを打ってください。

```console:ターミナル(ubuntu)
$curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
```

### パスを通してください、という文と以下のコマンドが出るので、コピペしてまたターミナルに打ちましょう。

```console:ターミナル
$echo 'PATH="/usr/local/heroku/bin:$PATH"' >> ~/.profile
```
gitの時と同じように以下のコマンドを打って、インストールしたバージョンが出てきたらインストールが成功しています。

```console:ターミナル
$heroku --version
>>heroku/7.0.47 darwin-x64 node-v10.1.0
```

はい、herokuのcliもインストールできたので、いよいよ自分のアプリとherokuを紐づけていきましょう！

### Railsアプリとherokuの紐づけ

まずは、自分のPCからherokuにログインします。（ここまでできているなら大丈夫だと思いますが、wi-fiに繋ぐのを忘れずに！）

### PCからherokuにログイン

```console:ターミナル
$heroku login
```

そうすると、herokuに登録したemailとpasswordの入力を求められるので、指示された通りに打ち込んでください。

### herokuに登録したemailとpasswordの入力


```console:ターミナル
Enter your Heroku credentials:
Email: ~~~~~@example.com  (ふっつーにherokuに登録したアドレス打ってください)
Password: **********  (ふっつーにherokuに登録したパスワード打ってください)
Logged in as ~~~~~@example.com
```

ログインしたら、以下のコマンドを打ってください。このコマンドはherokuとアプリを紐づけるコマンドなので、アプリごとに最初の一回だけで大丈夫です。

### アプリごとに最初の一回だけ！

```console:ターミナル
$heroku create 好きなアプリ名 (「好きなアプリ名」に入力する文字列はurlになるものです。_とか使えないので注意！)
```

「好きなアプリ名」は空欄にしてしまっても自動生成してくれるので大丈夫です。このようになっていたらおっけーです。

<img width="1120" alt="スクリーンショット 2018-05-19 12.05.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/f6a7c41d-c5d0-76ca-06b0-906814281dcd.png">

このように「Name is already taken...」となっていたら残念ながらそのアプリ名は他の方に取られちゃっています。変更しましょう。
<img width="1364" alt="スクリーンショット 2018-05-21 12.36.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/6bb8eaac-6533-df10-9d0e-7e7d28ca72d9.png">

では、いよいよデプロイになります。ターミナルに以下のコマンドを打ち込んでください。

### herokuにデプロイ

```console:ターミナル
$git push heroku master
```
(herokuを使うと、このようにコマンド一つでRailsアプリがデプロイできちゃいます。これで無料はすごい！)

こんな感じでデプロイが進んでいきます。
うまくいかない方は下にデバッグの方法をいくつか載せています。ご参照ください。

<img width="1440" alt="スクリーンショット 2018-05-21 12.46.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/6ebfa879-2b91-0b5b-c800-31ce03c8590c.png">

詳しくみていくと、このタイミングでproductionでの`bundle install`や

<img width="1440" alt="スクリーンショット 2018-05-21 12.47.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/70997593-0dcf-f6cb-dade-ea34464ae2ac.png">

rake assets:precompile(ざっくりいうと画像の表示)なども行われているのがわかると思います。

<img width="1440" alt="スクリーンショット 2018-05-21 12.47.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/744b705a-cdb7-1eae-cfb2-602ff146e88b.png">


さて、ここまで順調であれば、一番最後の方に

<img width="867" alt="スクリーンショット 2018-05-21 12.49.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/f91f9fce-9fc4-9f49-0e13-ddb85e9be433.png">

このように自分の指定したアプリ名を含んだurlが生成されていますが、これがまさに__自分のアプリのURL__になります。早速確認しにいきたいところなんですが、最後に以下のコマンドを入力してください。

本番環境でのデータベースのマイグレーションになります。

### 本番環境(heroku)でのマイグレーション

```console:ターミナル
$heroku run rails db:migrate
```

実行結果
<img width="1440" alt="スクリーンショット 2018-05-21 12.52.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/af58c9b9-97b9-6808-2754-6de998ea30d6.png">

このように`heroku run`をつけると__heroku上でrailsコマンド__を打つことができます。他にも`heroku run rails c`などなど、色々ありますので調べてみましょう。

以上でherokuでのデプロイは完了になります！早速、先ほどメモしたURLをブラウザのアドレスバーに貼り付けて、確認してみましょう。

<img width="679" alt="スクリーンショット 2018-05-21 13.01.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/208038/5e884131-b555-9780-7c56-4475151e3f9e.png">

お疲れ様でした！

## ここまでやったのに、 `git push heroku master` が通らない
Rubyのバージョンによっては、下のようにRubyのバージョンとHerokuのStack(HerokuのOSイメージ)のバージョンが合わずに下のようにエラーが出ることがあります。
詳しくは[こちら(Heroku公式ドキュメント)](https://devcenter.heroku.com/changelog-items/1485)をご覧ください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/208038/dd18d3f1-a29b-681e-ebc2-2d5e759ff716.png)

この場合はRubyのバージョンを新しくする ~~か、以下のコマンドでstackのバージョンをHeroku-18からHeroku-16に変更する~~ 必要があります。

下のコマンドは非推奨なのでこちらの記事を参考に直してください。(かなり昔に書いた解決策なのでご勘弁を・・・・。)
=> https://qiita.com/jnchito/items/c3035cc49a9cef053549

~~~linux:ターミナル
$ heroku stack:set heroku-16
~~~


## ここまでやったのに、 `heroku run rails db:migrate` が通らない

`heroku run rails db:migrate` が通らず、かつ下エラーが表示される場合は、Heroku上のアプリケーションにPostgresqlのアドオンが登録されていない可能性があります。

アドオン(add-on)とは、「拡張機能の追加」という意味です。

```console:ターミナル
PG::ConnectionBad: could not connect to server: No such file or directory
```

その場合、上記コマンドでアドオン登録を行った後、再度マイグレーション処理を実行すると、問題が解決する事があります。

```console:ターミナル
$heroku addons:add heroku-postgresql
```




## おまけ:更新の時

ここまでやった通り、herokuは__gitと連携して、gitに保存した内容をデプロイ__しています。なので、「アプリをちょっと変えたから変更したい」という時には、`git add`からコマンドを実行してください。

更新時の例:

```console:ターミナル
$git add -A
$git commit -m "Update application"
$git push heroku master
```

テーブル追加や内容変更などをした場合は、もちろんこちらのコマンドも打ってください。

```console:ターミナル
$heroku run rails db:migrate
```