webpackerを導入したRailsアプリケーションが手元ではちゃんと動いておりテストもパスした、あとはデプロイだけだ〜という段階で失敗した。
解決策
新しめの Ruby アプリケーション用の buildpack が使われるよう、BUILDPACK_URL
を正しく指定する。具体的には以下のように環境変数を与える。
deis config:set BUILDPACK_URL='https://github.com/heroku/heroku-buildpack-ruby'
# 特定のバージョンを指定する場合 deis config:set BUILDPACK_URL='https://github.com/heroku/heroku-buildpack-ruby#v170'
経緯メモ
2時間ぐらい試行錯誤したメモ。
Gem::GemNotFoundException
デプロイ失敗、Gem::GemNotFoundException
に出くわす。
2017-11-16T16:01:50UTC app-name[web.1]: /usr/lib/ruby/1.9.1/rubygems.rb:308:in `bin_path': can't find gem bundler (>= 0) (Gem::GemNotFoundException) 2017-11-16T16:01:50UTC app-name[web.1]: from /app/bin/bundle:3:in `<main>'```
Rails | `bin_path': can't find gem bundler に対処する - Qiita に書かれているように bundler を install し直せばよいのか?と思ったが、ruby 1.9.1 というのがそもそもおかしいと気付く。
Deis's app detection system is not smart
Slack の過去ログを Gem::GemNotFoundException
で検索したら過去に似たような事例があり、どうやらpackage.json
が ルートディレクトリにあると Deis が Node.js アプリケーションだと判定するらしいとわかる。
deis のコードでいうとこのへん。たしかにこのへんでダウンロードした buildpacks をループで回して最初にマッチしたものを選択しているだけなので nodejs > ruby の優先順になりそうだ。
git rm package.json
過去ログでは deploy 直前に git rm package.json
してから push するというワークアラウンドで回避していたので一旦それを試してみる。
remote: [1G[1G Webpacker requires Node.js >= 6.0.0 and you are using 0.10.30[K remote: [1G[1G Please upgrade Node.js https://nodejs.org/en/download/[K
heroku-buildpack-ruby が使われるようになったはよいが、違う理由で失敗した。Node.js バージョンが古いので webpacker が使えないようだ。
ここで使っている Node.js バージョンは buildpack 側で指定しているもので、そもそも Deis が preinstall している buildpack のバージョンがやや古めと SRE メンバーに教えてもらった。
Set BUILDPACK_URL
v150を指定しているが CHANGELOG によると webpacker をサポートし始めたのは v155 から。
冒頭に述べたように環境変数 BUILDPACK_URL
があればそれを使うようになっているとのことなので指定した。
2時間ぐらいかけて遂にデプロイできた。 👏
Heroku では起きない
余談だが Heroku ではデフォルトで最新の buildpack が使われるはずなのでこうした問題は起きないはず。
また、buildpack のアップデート時に非互換のでかい変更がブッ込まれるのはそうそう無い印象なので一旦はバージョン固定なしで運用してみる。
所感
インフラとして使っているのにも関わらず Deis のコードを読むのは初めてで新鮮。PaaS のコードが読めるって凄いことだな、と思うなど。
ラストワンマイルはいつも大変。