docker で Run `bundle install` to install missing gems になっちゃう件

Docker で Gemfile に変更があったときだけ bundle install を実行するために、 Gemfile と Gemfile.lock を先に ADD しておいて bundle install を先に実行しておくのはもはや常識だと思う。

ちょいちょい例にこういうのがある。(ここでは Dockerfile とアプリケーションが同じリポジトリディレクトリ)にあるとして、そのディレクトリで docker build してるとする)

WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock

....

ADD . /app

どういうのかというと、 bundle install を先に実行してキャッシュを作るときのディレクトリと、実際にアプリが動くディレクトリを別にしているという例。

これは通常問題ないんだけど、bundle install の際につけるオプションによっては問題になる。

例えば bundle install –without development test とかする場合。

/tmp 以下には install 時に .bundle/config が作られてそこに BUNDLE_WITHOUT の情報が書き込まれるので、特定の group が除外されていることがちゃんと bundler に伝わる。

しかし、↑でいうと /app 以下で bundle exec とかするときにはその情報は伝わらないので、without オプションを指定して意図的に除外した group の gem がインストールされていないと、タイトルに書いたようなエラーが出てしまう。

解決策としては普通にアプリを動かすディレクトリで bundle install をやっておけばいい ( bundle config --global without development:test[:…] とする手もある )