Docs header transparent bg

如何將 Bundler 與 Docker 搭配使用

簡介

Ruby 的官方 Docker 映像假設您只會使用一個應用程式,搭配一個 Gemfile,而且不會在您的容器中安裝或執行其他寶石或 Ruby 應用程式。

如果您想在容器中安裝多個 Gemfile,或只是透過 RubyGems 安裝寶石並將它們用作系統寶石,這種情況會令人困惑,而且歷來導致許多令人困惑的錯誤,這些錯誤看起來像是 Bundler 中的錯誤。

然而,這些錯誤最終來自於 Dockerfile 告訴 Bundler 在整個容器中建立 binstub(連結至一個應用程式和 Gemfile)的單一全域位置的方式。例如,如果您使用 rake 安裝兩個 Gemfile,執行 rake 指令時,它將永遠載入最後安裝的 Gemfile,而不會載入任何其他 Gemfile。

多個 Ruby 應用程式和寶石的 Dockerfile

若要建立一個可以執行多個 Ruby 應用程式或使用 gem install 安裝的全域指令的 Docker 容器,您需要變更 Ruby 官方 Docker 映像中設定的預設值中的一些環境變數。

在您的 Dockerfile 中,變更 PATHGEM_HOME,讓 Bundler 將所有寶石安裝到相同的位置,而且執行指令時將使用 RubyGems binstub,而不是 Bundler 的應用程式鎖定的 binstub

ENV GEM_HOME="/usr/local/bundle"
ENV PATH $GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH

您還需要取消設定 BUNDLE_PATHBUNDLE_BIN。在 Docker 中取消設定環境變數可能會有點棘手,但最常見的方式是在您的 ENTRYPOINT 腳本的開頭

#!/bin/bash

unset BUNDLE_PATH
unset BUNDLE_BIN

# your script goes here

完成後,您將能夠直接呼叫指令來執行它們,而不需要 bundle,例如 rake。您可以透過 cd 到該 bundle 的目錄,然後使用 bundle exec 來執行特定 bundle 中的指令。例如,若要在應用程式 bundle 內執行 rake,您會使用 bundle exec rake