Herokuでデプロイに失敗するときの対処法(Ruby app detected されない問題)

Herokuで[自作アプリ](supplebox.jp)を運用していますが、ビルド時にエラーになる現象に遭遇しました。

Heroku特有のエラーであり、インターネット上に情報があまりなかったので、解決の手順をまとめます。

## Build Logを見る
コンソールのActivityからBuild Logを見ます。
失敗時のログと正常時のログを見比べてみるとは、失敗時は`Ruby app detected`や`Installing bundler 2.0.2`などと、Rubyのアプリケーション特有のBuild関連の処理がされていないことがわかりました。

**失敗時**

```
-----> nginx-buildpack app detected
./
./nginx
./mime.types
./nginx-debug
-----> nginx-buildpack: Installed nginx/1.18.0 to app/bin
-----> nginx-buildpack: Added start-nginx to app/bin
-----> nginx-buildpack: Added start-nginx-debug to app/bin
-----> nginx-buildpack: Added start-nginx-solo to app/bin
-----> nginx-buildpack: Default mime.types copied to app/config/
-----> nginx-buildpack: Default config copied to app/config.
-----> Discovering process types
       Procfile declares types -> web
-----> Compressing...
       Done: 4.9M
-----> Launching...
       Released v154
       https://supplebox.herokuapp.com/ deployed to Heroku
...略
```

**正常時**

```
-----> Ruby app detected
-----> Installing bundler 2.0.2
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.7.1
-----> Installing dependencies using bundler 2.0.2
       Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
       [DEPRECATED] The `--deployment` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set deployment 'true'`, and stop using this flag
       [DEPRECATED] The `--path` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set path 'vendor/bundle'`, and stop using this flag
       [DEPRECATED] The `--without` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set without 'development:test'`, and stop using this flag
       [DEPRECATED] The --binstubs option will be removed in favor of `bundle binstubs`
       Fetching gem metadata from https://rubygems.org/............
       Using rake 13.0.1
...略
```

## Rubyアプリとして認識してくれていないみたい
`Ruby app detected`されていないのが原因のよう。
Herokuは、Railsアプリケーションならば自動的にRuby用のビルドをしてくれているという認識でしたが、この辺の処理について調べてみました。

- HerokuのRubyサポートについて https://devcenter.heroku.com/articles/ruby-support#rails-6-x-applications

- Herokuのビルドパックについて https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app#adding-a-buildpack

どうやら、HerokuはソースコードからRubyアプリケーションであることを自動検知して、一連のビルドプロセスのまとまり(ビルドパック)を使ってアプリケーションを自動ビルドしてくれているようです。

今回の事象については、Rubyのビルドパックが起動していないことが原因なので、手動でビルドパックを追加してみます。

## ビルドパック追加
https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app#adding-a-buildpack

を参考に、現状のビルドパックを確認し、追加します。

もともと`heroku-community/nginx`というビルドパックがありましたが、`heroku/nodejs`と`heroku/ruby`というビルドパックを`index`オプションを使って順番を指定してインストールしました。

```bash
$ heroku buildpacks
=== supplebox Buildpack URL
heroku-community/nginx

$ heroku buildpacks:add --index 1 heroku/nodejs
Buildpack added. Next release on supplebox will use:
  1. heroku/nodejs
  2. heroku-community/nginx
Run git push heroku main to create a new release using these buildpacks.

$ heroku buildpacks:add --index 2 heroku/ruby
Buildpack added. Next release on supplebox will use:
  1. heroku/nodejs
  2. heroku/ruby
  3. heroku-community/nginx
Run git push heroku main to create a new release using these buildpacks.
```

## 再ビルド。治った!!
Herokuは再ビルドができないようなので、空コミットなりのPRをマージしてデプロイしなおします。

そして、治りました。

Build Logに`Ruby app detected`と表示され、Ruby関連のビルドが正常に動き、正常にデプロイできました。

めでたし。