Stan Blog

記錄學習到的東西

[Rails] gemfile deployment mode 的保護機制

前言

前陣子被朋友問一個 rails 在 production 上 bundle 找不到某個 gem 的問題

後來他突發奇想在機器內專案的 gemfile 註解掉其中一個 gem 去 deploy

結果發生這個錯誤

You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.

If this is a development machine, remove the /home/apps/xxx/releases/20200619033835/Gemfile freeze
by running `bundle install --no-deployment`.

You have deleted from the Gemfile:
* source: git@github.com:xxx-organization/xxx-gem.git (at master@17ffa54)
 xxx-gem (~> 1.0.2)

首先在 stackoverflow 查到了 這篇,看起來是保護機制。避免在 deploy 時,修改了 gemfile 但沒有跑 bundle。發生與 gemfile.lock 內容不符的情形

bundler 的說明

 # Frozen ensures that the Gemfile and the Gemfile.lock file are matching.
 # This stops a situation where a developer may update the Gemfile but may not run
 # `bundle install`, which leads to the Gemfile.lock file not being correctly updated.

因為第一次看到這個錯誤,有點好奇。就開啟了挖掘之旅

尋找 source code

首先在 bundler 內找到定義錯誤的 method ensure_equivalent_gemfile_and_lockfile (bundler/lib/bundler/definition.rb)

接著看一下 installer call 到指定 method 的地方 (bundler/lib/bundler/installer.rb)

發現 frozen_bundle? 是 true 才會執行

frozen_bundle? 的定義 bundler/lib/bundler.rb

在 bundler 的 官方文件 可以看到 frozen (BUNDLE_FROZEN): Disallow changes to the Gemfile. When the Gemfile is changed and the lockfile has not been updated, running Bundler commands will be blocked. Defaults to true when --deployment is used.

frozen 預設值是 true,也就是保護機制預設是開啟的

可以在專案下執行 $ bundle config 看目前的設定

或是直接查看家目錄底下的 bundle config $ vim ~/.bundle/config

那 deployment 又是什麼呢?

bundler 官方文件 參數的說明

deployment
In deployment mode, Bundler will 'roll-out' the bundle for production use. Please check carefully if you want to have this option enabled in development or test environments.

在 production 預設啟用 deployment mode,而在 development、test 則需要另外開啟

Ref:

Comments

comments powered by Disqus