Docs header transparent bg

如何在 Docker 中使用 Bundler

简介

Ruby 的官方 Docker 镜像假设您只使用一个应用程序,一个 Gemfile,并且容器中不会安装或运行其他 gem 或 Ruby 应用程序。

如果您想在容器中安装多个 Gemfile,或者只是通过 RubyGems 安装 gem 并将其用作系统 gem,这种情况会很混乱,并且历史上会导致许多令人困惑的错误,这些错误似乎是 Bundler 中的错误。

但是,这些错误最终来自 Dockerfile 如何告诉 Bundler 在整个容器的单个全局位置创建 binstubs(与一个应用程序和 Gemfile 链接)。例如,如果您使用 rake 安装了两个 Gemfile,则运行 rake 命令将始终加载最后安装的 Gemfile,而不会加载其他任何 Gemfile。

用于多个 Ruby 应用程序和 gem 的 Dockerfile

要构建一个可以运行多个 Ruby 应用程序或使用 gem install 安装的全局命令的 Docker 容器,您需要更改 Ruby 官方 Docker 镜像中设置的默认值的一些环境变量。

在您的 Dockerfile 中,更改 PATHGEM_HOME,以便 Bundler 将所有 gem 安装到同一位置,并且运行命令将使用 RubyGems binstubs 而不是 Bundler 的应用程序锁定 binstubs。

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

完成此操作后,您将能够通过直接调用命令(如 rake)来运行命令,而无需捆绑。您可以通过 cd 到该捆绑包的目录,然后使用 bundle exec 来在特定捆绑包中运行命令。例如,要在应用程序捆绑包中运行 rake,您将使用 bundle exec rake

在 GitHub 上编辑此文档,如果您发现错误或遗漏。