【初心者向け】RailsチュートリアルでHerokuデプロイ時に「Ruby 2.6.3はインストールできない」と言われたときの適切な対処方法

注：この情報は2021年2月19日時点の情報です。将来的には記事内のバージョン番号等が変わる可能性があります。

## この記事の3行まとめ

- RailsチュートリアルでRubyのバージョンが原因でHerokuへのデプロイに失敗した場合は、Gemfileから`ruby '2.6.3'`の行を削除する（Railsチュートリアルが推奨する解決方法）
- Herokuのstackを20から18に下げるのは対応方法として好ましくない
- Cloud9上にRuby 2.6.6をインストールし、開発環境でもHerokuでも同じRubyバージョンを使えるようにするのが本来であればベスト

具体的な内容は以下で詳しく説明していく。

## Herokuデプロイ時に発生する問題とその原因

[Railsチュートリアルの第1章](https://railstutorial.jp/chapters/beginning?version=6.0)の内容に従ってhello_appを作成し、Herokuにデプロイしようとすると以下のようなエラーが出てデプロイに失敗することがある。

```
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 441 bytes | 441.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Building on the Heroku-20 stack
remote: -----> Ruby app detected
remote: -----> Installing bundler 1.17.3
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote:        Command: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-20/ruby-2.6.3.tgz -s -o - | tar zxf - ' failed on attempt 1 of 3.
remote:        Command: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-20/ruby-2.6.3.tgz -s -o - | tar zxf - ' failed on attempt 2 of 3.
remote: 
remote:  !
remote:  !     The Ruby version you are trying to install does not exist on this stack.
remote:  !     
remote:  !     You are trying to install ruby-2.6.3 on heroku-20.
remote:  !     
remote:  !     Ruby ruby-2.6.3 is present on the following stacks:
remote:  !     
remote:  !     - cedar-14
remote:  !     - heroku-16
remote:  !     - heroku-18
remote:  !     
remote:  !     Heroku recommends you use the latest supported Ruby version listed here:
remote:  !     https://devcenter.heroku.com/articles/ruby-support#supported-runtimes
remote:  !     
remote:  !     For more information on syntax for declaring a Ruby version see:
remote:  !     https://devcenter.heroku.com/articles/ruby-versions
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !	Push rejected to jnchito-hello-app.
remote: 
To ssh://heroku.com/jnchito-hello-app.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://git@heroku.com/jnchito-hello-app.git'
```

エラーの内容を翻訳すると、次のようなことが書いてある。

> あなたがインストールしようとしたRubyバージョンはこのstackには存在していません。
> あなたはruby-2.6.3をheroku-20にインストールしようとしています。
> Ruby 2.6.3は以下のstackに存在しています。
>
> - cedar-14
> - heroku-16
> - heroku-18
> 
> Herokuでは以下のページにリストアップされている、最新のサポートバージョンのRubyを使うことを推奨しています。
> https://devcenter.heroku.com/articles/ruby-support#supported-runtimes
>
> Pushは拒否され、Rubyアプリケーションのコンパイルに失敗しました。
> Pushは失敗しました。

エラーメッセージに書いてあるとおり、HerokuではRuby 2.6.3というバージョンが使えない、ということがデプロイ失敗の原因になっている。
本記事執筆時点ではCloud9ではRuby 2.6.3がデフォルトで使用されるため、HerokuがサポートしているRubyバージョン（Ruby 2.6.6以上）とのミスマッチが発生し、エラーが起きるのである。

この問題の解決方法を以下で説明する。

## 最も手軽な解決方法（おすすめ）

Gemfileを開き、`ruby '2.6.3'`となっている行を削除し、ファイルを保存する。

```diff:Gemfile
 source 'https://rubygems.org'
 git_source(:github) { |repo| "https://github.com/#{repo}.git" }
-ruby '2.6.3' # ←この行を削除する
```

ターミナルから`bundle install`を実行する。

```
bundle install
```

ターミナル上で以下のコマンドを実行し、変更点をコミットする。

```
git commit -a -m "Remove ruby version"
```

それからもう一度Herokuにデプロイする。

```
git push heroku master
```

こうすればHerokuが自動的にRuby 2.6.6を使うようになり、デプロイに成功する。
場合によっては違うエラーが起きるかもしれないが、少なくとも"The Ruby version you are trying to install does not exist on this stack."というエラーメッセージではなくなるはずだ。

### この方法はRailsチュートリアルが公式に推奨している

この解決方法（行削除の指示）はRailsチュートリアルにもしっかり書いてある。
つまり、Railsチュートリアルが公式に推奨している解決方法である。

> 最後に、Rubyの正確なバージョン番号を指定する行（ruby '2.6.3'）をリスト 1.5から削除している点に注意してください。業務でWebサービスを開発する場面では削除しないことをオススメしますが、本チュートリアルでは、この行が残っているとエラーになる可能性が高まります。
>
> https://railstutorial.jp/chapters/beginning?version=6.0#sec-bundler

この指示を見逃していると、Herokuデプロイ時に"The Ruby version you are trying to install does not exist on this stack."のエラーに遭遇してしまう。

### ただし、この解決策は学習目的に限定する

上のRailsチュートリアルの引用文にもあるとおり、業務で開発する場合はGemfileからRubyのバージョンを削除するのは望ましくない。
**業務でHerokuを使うのであれば後述する「最も望ましい解決方法」を採用すべきである。**

GemfileからRubyのバージョンを削除するのはあくまで学習目的に限定した解決策であることに留意されたい。

## stackのバージョンを下げるのはNG！！

このエラーメッセージでググったときに引っかかるQiitaの記事では「heroku-20を使っているのが原因なので、Herokuのstackをheroku-18に変更しましょう」という解決策が載っていることが多い。
しかし、筆者はこの方法は推奨しない。

なぜなら、stackのバージョンを下げると、アプリケーションのパフォーマンスが悪化したり、stackのサポート終了日が早くやってくるなどのデメリットがあるからだ。

```
# stackのバージョンは下げちゃダメ！！
heroku stack:set heroku-18
```

プログラマの世界では何事も「最新バージョンが最高のバージョン」という考え方が基本原則となる。
stackを20から18にわざわざ下げることはこの基本原則に逆行する行為なので、可能なかぎり避けるべきである。

実際、冒頭に載せたエラーメッセージにも次のような文言が書かれている。

> Heroku recommends you use the latest supported Ruby version listed here:
> https://devcenter.heroku.com/articles/ruby-support#supported-runtimes

（筆者訳）

> Herokuでは以下のページにリストアップされている、最新のサポートバージョンのRubyを使うことを推奨しています。
> https://devcenter.heroku.com/articles/ruby-support#supported-runtimes

[リンク](https://devcenter.heroku.com/articles/ruby-support#supported-runtimes)を開くと、一番古いサポートバージョンはRuby 2.6.6になっている。（2021年2月19日時点の情報）
よって、HerokuとしてはRuby 2.6.3ではなく、2.6.6を推奨していることがわかる。

![Screen Shot 2021-02-19 at 22.40.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/022589f7-e429-fbe6-121a-12756f812ac9.png)

エラーメッセージにはたしかに「Ruby 2.6.3はheroku-18に存在している」と書かれているが、だからといってHerokuはheroku-18 stackを使うことを推奨しているわけではない点に注意されたい。

### すでにstackを下げてしまっている場合

すでにstackを下げてしまっている場合はターミナルから以下のコマンドを実行して、stack-20に戻す。

```
heroku stack:set heroku-20
```

それから上で説明した「最も手軽な解決方法」の手順に従えば良い。

## 最も望ましい解決方法（やや上級者向け）

Gemfileから`ruby '2.6.3'`を削除する方法では、開発中（Cloud9上）はRuby 2.6.3を、Herokuデプロイ時にはRuby 2.6.6を使う対処方法になる。
Railsチュートリアルのような簡単なRailsアプリケーションでは2.6.3と2.6.6の違いで何か問題が起きる可能性は少ないと思うが、本来であれば開発時もHerokuデプロイ時も全く同じRubyバージョンを使うことが望ましい。
そこで、以下ではCloud9上でもRuby 2.6.6を使えるようにする方法を説明する。

まず、ターミナル上で以下のコマンドを入力してCloud 9の実行環境にRuby 2.6.6をインストールする。

```
rvm install "ruby-2.6.6"
```

続いて以下のコマンドを入力してRubyの実行バージョンを2.6.3から2.6.6に変更する。

```
rvm use 2.6.6
```

念のため、`ruby -v`を実行してRuby 2.6.6に切り替わったことを確認しておこう。

```
$ ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
```

次にGemfileを開いて`ruby '2.6.3'`を`ruby '2.6.6'`に変更し、ファイルを保存する。

```diff:Gemfile
 source 'https://rubygems.org'
 git_source(:github) { |repo| "https://github.com/#{repo}.git" }
-ruby '2.6.3'
+ruby '2.6.6'
```

さらに、`bundle install`を実行する。

```
bundle install
```

ここまでの変更点をコミットする。

```
git commit -a -m "Use Ruby 2.6.6"
```

これでRuby 2.6.6への切り替えができたので、問題なくHerokuにデプロイできるはずだ。

```
git push heroku master
```

業務で開発するRailsアプリケーションであれば、このような対応方法を採るのがベストである。

### rbenvを使う場合

Cloud9ではRubyのバージョン切り替えツールとしてRVMが使われているが、ローカルマシンで開発していてrbenvを使っている場合は次のような手順になる。

```
$ rbenv install 2.6.6
$ rbenv local 2.6.6
$ ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-darwin19]
```

`ruby -v`からあとの手順はRVMの場合と同様。

## まとめ

この記事の内容をあらためて以下にまとめておく。

- RailsチュートリアルでRubyのバージョンが原因でHerokuへのデプロイに失敗した場合は、Gemfileから`ruby '2.6.3'`の行を削除する（Railsチュートリアルが推奨する解決方法）
- Herokuのstackを20から18に下げるのは対応方法として好ましくない
- Cloud9上にRuby 2.6.6をインストールし、開発環境でもHerokuでも同じRubyバージョンを使えるようにするのが本来であればベスト

本記事がHerokuデプロイ時にエラーが出て困っているプログラミング初心者の参考になれば幸いである。

### 謝辞
本記事の執筆にあたり、Railsチュートリアルの運営会社である[YassLab 株式会社](https://yasslab.jp/)の安川さん（ @yasulab ）に執筆内容を監修していただきました。
安川さん、どうもありがとうございました！