valid,invalid

関心を持てる事柄について

webpackerを導入したRailsアプリケーションをDeisにデプロイする

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 のコードが読めるって凄いことだな、と思うなど。

ラストワンマイルはいつも大変。