概要
ローカル環境でも厄介なGemのdefault設定。
「このバージョンのGemで運用していきたいのに!」といった気持ちに反して、bundle installすると、default設定されたバージョンでインストールされてしまう。。。
ローカル環境ではその解除はできるが、Dockerのコンテナ内では少しだけ訳が違ったので、まとめたいと思い本記事を制作しました。
不足点、誤りがあれば遠慮なくご指摘いただけますと幸いです。
2021/4/10追記
コメント欄にてとても有益なコメントを頂きました。下記に引用させていただきます。
defaultが付いているgemは、Rubyの言語処理系が組み込みで内包しているものなので、色々なgemの前提として利用されている可能性が高いものです。
そのgemspecをまとめて削除してしまうと、それらの前提となっているgemが認識されなくなり、その他のgemが壊れる可能性があるので、オススメできません。
bundler以外のgemに関しては、bundlerとGemfile.lockを使ってバージョンを固定して運用しましょう。default gemであってもGemfileに記載すれば任意のバージョンで実行できます。
bundlerに関しては、余り知られていない可能性がありますがrubygems自体がバージョンを指定してコマンドを実行する機能を持っているので、そちらを利用するのが良いでしょう。
今後はこちらの方法を使うことをお勧めします。
私もこの方法にてバージョン指定を行いました。
経緯
これまでローカル環境にて開発を行い、いざ本番環境へデプロイ!となるとエラーが返され、苦い思いをしてきた私。
今回はdocker-compose up
で立ち上げたコンテナ内でgem list
を見ると、ローカルでのgem list
とバージョンの違いが生じていました。
そこで、コンテナ内でも指定したバージョンのGemで運用したく奮闘したのが経緯です。
方法
①コンテナ内に入る
ローカルにて自身のアプリのディレクトリにて
% docker-compose exec web bash
root@コンテナID:/アプリ名# 以降プロンプト以外は省略します
②Gemを確認(省略可能)
# gem list bundler ※ちなみに全てのGemをリスト化するには"bundler"を省略
*** LOCAL GEMS ***
bundler (2.1.4, default: 1.17.2)
**この忌々しいdefaultを解除していきます。
③default設定されているGemのありかを探る。
# gem environment
RubyGems Environment:
...略
- INSTALLATION DIRECTORY: /usr/local/bundle
- USER INSTALLATION DIRECTORY: /root/.gem/ruby/2.6.0
...略
- GEM PATHS:
- /usr/local/bundle
- /root/.gem/ruby/2.6.0
- /usr/local/lib/ruby/gems/2.6.0
...略
ここでちなみにローカルで同様にgem environment
コマンドを実施した時の結果を下記に記します。
% gem environment
RubyGems Environment:
...略
- INSTALLATION DIRECTORY: /Users/ユーザー/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0
- USER INSTALLATION DIRECTORY: /Users/ユーザー/.gem/ruby/2.6.0
...略
- GEM PATHS:
- /Users/ユーザー/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0
- /Users/ユーザー/.gem/ruby/2.6.0
...略
INSTALLATION DIRECTORYに注目してください。
指定されているディレクトリがわずかに違います。
⑤の項目にてさらに解説します。
④ホームに戻る
# cd
root@コンテナID:~#
⑤default設定のあるディレクトリまでたどり着く
ここで、ローカル環境でのたどり着き方の場合は、INSTALLATION DIRECTORYに記載されているパスまでcdコマンド
で行けばいいのですが・・・
ローカルの場合!
% cd /Users/ユーザー/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0
ユーザー@PC 2.6.0 %
コンテナ内の場合!!
# cd /usr/local/lib/ruby/gems/2.6.0
root@コンテナID:/usr/local/lib/ruby/gems/2.6.0#
INSTALLATION DIRECTORYに記載されているパスでは「そんなディレクトリは無い!!」と怒られたので、別のディレクトリを探したところ,
GEM PATHSに記載のあったディレクトリが正解だったようです。
⑥specificationsの中のdefaultを削除する
lsコマンド
を使ってみると、このディレクトリの中にspecifications
というディレクトリがあるはずです。
この中にdefault設定があります。
※気になる方はここで、cd specifications
して、lsコマンド
をすると、default
と記載のあるGemがいくつかあると思います。
# rm -rf specifications/default/
これでspecifications内のdefaultディレクトリが全て削除されます。
⑦念の為、確認。
# gem list bundler
*** LOCAL GEMS ***
bundler (2.1.4)
bundlerのdefaultが解除されています。
ここでbundle installし、Gemfile.lockを確認すると最後の行に・・・
BUNDLED WITH
2.1.4
と、自分の好きなバージョンでバンドルされていることが確認できました!
考察
ここで学んだことが2つあります。
まず1つ
当然ではありますが、ローカル環境とコンテナ環境は別物。Gemのバージョンの相違に気づけたこと。
もう1つ
同じgem environment
に返される結果は、似てこそあれども微妙な違いがあること。
自分の求める情報はどこに記載があるのか注視しなければならない。
これまでデプロイの時に何かしらのエラーに叩きのめされていたので、docker使用時に未然にGemのバージョンを合わせれて良かったと思います。
誰かの参考になれば幸いです。
ありがとうございました。