【问题标题】:Elastic Beanstalk: can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)Elastic Beanstalk:找不到带有可执行包 (Gem::GemNotFoundException) 的 gem bundler (>= 0.a)
【发布时间】:2019-08-17 00:45:03
【问题描述】:

此错误消息是众所周知的错误消息。 (例如,请参阅https://bundler.io/blog/2019/01/04/an-update-on-the-bundler-2-release.html。)虽然我正在使用带有 Ruby 2.6.1 和 bundler 2.0.1 的新 Elastic Beanstalk 应用程序来获得它。错误是:

  /opt/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
from /opt/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems.rb:308:in `activate_bin_path'
from /opt/rubies/ruby-2.6.1/bin/bundle:23:in `<main>' (ElasticBeanstalk::ExternalInvocationError)

我尝试将以下文件:01_install_bundler.config 放入 .ebextensions 文件夹中:

container_commands:
  01_install_bundler:
    command: "gem install bundler —-version 2.0.1"

虽然这永远不会运行,因为如果我查看上述错误,我可以看到它在部署过程中的这一点发生:

.../AppDeployStage0/AppDeployPreHook/10_bundle_install.sh] : Activity failed.

(即在 AppDeployPreHook 脚本的 bundle install 命令期间)。 PlatformHooks 参考https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/custom-platform-hooks.html

我很确定,如果我能确保使用的 bundler 版本至少是 2.0.0 版,那么就不会有问题。虽然我不知道如何轻松指定。目前我正在通过 ssh'ing 到服务器 /opt/elasticbeanstalk/hooks/appdeploy/pre/ 来编辑和修改脚本。虽然我显然需要一种自动化的、可重复的方式来做这件事。

令人沮丧的是,ruby 2.6.1 默认没有选择捆绑器版本 2.0.0。有什么想法吗?

================================

更新:

如果我编辑文件/opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh

if [ -f Gemfile ]; then
  echo "running 'bundle install' with Gemfile:"
  cat Gemfile

  +++ gem install bundler +++
  if [ -d $EB_APP_STAGING_DIR/vendor/cache ]; then
    bundle install --local
  else
    bundle install
  fi
else
  echo "no Gemfile found! Skipping bundle install stage!"
fi

并添加gem install bundler(没有加号),然后这解决了问题,因为它安装了最新的捆绑程序,即 2.0.1。对于那些想知道 hack 的人来说,命令是:

eb ssh

sudo -i

cd /opt/elasticbeanstalk/hooks/appdeploy/pre

vim 10_bundle_install.sh

这个解决方案的问题是它感觉有点像黑客,因为它不使用.ebextensions。有没有更合适的方法来解决这个问题?

【问题讨论】:

  • 尝试了10_bundle_install.sh1 hack 并让 EB 抱怨我不应该尝试以 root 身份安装 Bundler。
  • @NBarnes,这可能是因为当您运行 eb deploy 时,您可能正在连接您的根 AWS 账户的 aws_access_key 和 aws_secret_access_key。 AWS 建议您为此目的使用身份访问管理 (IAM)。设置起来并不难。在 IAM -> 用户下,您只需创建一个具有以下权限的用户:AWSElasticBeanstalkFullAccessElasticLoadBalancingFullAccess。然后为该用户创建访问密钥并使用该配置文件运行eb deploy
  • 根据您的建议,我使用 IAM 创建了一个新用户并授予他们这两个权限。但是,我仍然收到有关以 root 身份运行 Bundler 的错误。我确实在 AWS CLI 中重置了凭证; cat ~/.aws/config 显示非 root 用户的访问密钥。编辑:问题可能是在下面的扩展文件 sn-p 中您将owner 设置为root
  • 我不确定@NBarnes。下面rootowner 是文件所有者。虽然听起来您的错误是在谈论用户在执行该文件时是root,而不是文件本身归root 所有。如果您在 Google 上搜索“以 root 身份安装 Bundler”,可能会有一些解释。也许您的 AWS 环境与我的不同?我正在运行Passenger with Ruby 2.6 running on 64bit Amazon Linux/2.9.1

标签: ruby-on-rails ruby amazon-web-services rubygems amazon-elastic-beanstalk


【解决方案1】:

所以这是上述问题的编程解决方案。在.ebextensions/gem_install_bundler.config下创建如下文件:

files:
  # Runs before `./10_bundle_install.sh`:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/09_gem_install_bundler.sh" :
    mode: "000775"
    owner: root
    group: users
    content: |
      #!/usr/bin/env bash

      EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
      EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
      # Source the application's ruby, i.e. 2.6. Otherwise it will be 2.3, which will give this error: `bundler requires Ruby version >= 2.3.0` 
      . $EB_SCRIPT_DIR/use-app-ruby.sh

      cd $EB_APP_STAGING_DIR
      echo "Installing compatible bundler"
      gem install bundler -v 2.0.1

那么下次eb deploy时,bundler 已经更新到 2.0.1 版本,不会再出现上述错误。

这里的文档中的更多信息:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/custom-platform-hooks.html

这里:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-files

最后一点:确保在运行eb deploy 之前提交这些更改,或者暂存它们并运行eb deploy --staged。请参阅:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb3-cli-git.html。我很难学到这一点!

【讨论】:

  • 我添加了这个文件,但仍然出现同样的错误,奇怪的是我没有得到回声,但在存档中有根级别的 .ebextensions/gem_install_bundler.config 文件 - 是还有什么我必须做的吗?我正在使用 Ruby 2.6.3
  • 如果你没有得到echo,那么它根本就没有执行。尝试将 echo 作为要执行的第一条语句移动,以防上述命令失败。
  • 我必须在文件末尾添加gem update --system,它解决了问题:)
  • 这对我有用。在我的特殊情况下,我必须将 Bundler 版本设置为 2.0.2 而不是 2.0.1。
  • “自定义平台挂钩是 Amazon Linux AMI 平台上的一项遗留功能。在 Amazon Linux 2 平台上,/opt/elasticbeanstalk/hooks/ 文件夹中的自定义平台挂钩已完全停用。” docs.aws.amazon.com/elasticbeanstalk/latest/dg/…
【解决方案2】:

我只是在找到替代(可能更简单)的解决方案后才看到这篇文章:将 bundler 降级到 1.17.3(gem unistall bundler 跟进gem install bundler -v 1.17.3

【讨论】:

    【解决方案3】:

    您需要生成锁定文件时使用的正确版本的捆绑程序。要找出该版本,请使用以下命令

    $ cat Gemfile.lock | grep -A 1 "BUNDLED WITH"
    BUNDLED WITH
       1.17.3
    

    【讨论】:

      【解决方案4】:

      这是一个可在新的 Amazon Linux 2 平台版本上使用的版本,因为旧的 /opt/elasticbeanstalk/hooks/ 文件夹已完全停用。它从 Gemfile.lock 中解析出 bundler 版本

      此脚本将进入.platform/hooks/prebuild/01_install_app_bundler.sh,并且需要将其标记为可执行,否则它将因权限问题而失败 (chmod +x 01_install_app_bundler.sh)

      #!/usr/bin/env bash
      
      # Load environment data
      EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppStagingDir)
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppUser)
      EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppDeployDir)
      
      # Set up correct environment
      export $(cat /opt/elasticbeanstalk/deployment/env | xargs)
      
      BUNLDER_VER_TO_INSTALL=$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n1 | tr -d ' ')
      
      echo "Installing bundler $BUNLDER_VER_TO_INSTALL"
      gem install bundler -v $BUNLDER_VER_TO_INSTALL
      

      我在其中留下了一些未使用的 EB_ 变量,只是为了说明如何在更新的平台上确定它们。

      【讨论】:

        猜你喜欢
        • 2019-05-31
        • 2018-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        • 1970-01-01
        • 2018-01-22
        • 2018-07-05
        相关资源
        最近更新 更多