【问题标题】:Customize AWS ElasticBeanstalk NodeJS Install (use yarn)自定义 AWS ElasticBeanstalk NodeJS 安装(使用 yarn)
【发布时间】:2017-05-30 03:51:00
【问题描述】:

是否可以配置 EBS 以使用 yarn 包管理器而不是 NPM 来安装我的 NodeJS 应用程序?

【问题讨论】:

  • 我决定在将存档上传到 Elastic Beanstalk 之前使用 Yarn 安装 Node 包,并将 node_modules 包含到存档中。 node_modules 的存在将使 NPM 跳过安装。它比答案中的解决方案更容易、更可靠。
  • @Finesse 这会阻止 Elastic Beanstalk 运行 npm install 并覆盖您的 node_modules 文件夹的内容吗?
  • @ebaynaud 它不会阻止 Elastic Beanstalk 运行 npm install。它使 NPM 什么也不做。

标签: node.js amazon-web-services npm amazon-elastic-beanstalk yarnpkg


【解决方案1】:

由于get-config 不再出现在新的 Amazon Linux 2 平台中,我们不得不想出另一种干净的方法来做到这一点,并提出了以下建议:

container_commands:
  01_npm_install_yarn:
    command: "npm install -g yarn"
  10_yarn_install:
    command: 'PATH="$PATH:$(dirname $(readlink $(which node)))" yarn install'

您可能希望将PATH= 逻辑放在脚本中并在每个纱线命令之前调用它,以便在您的扩展中包含干净的command: 指令。

另外,请注意,如果您使用 yum 包管理器安装 yarn,您将完全破坏 Beanstalk 提供的 NodeJS 版本管理(因为它背后运行的黑魔法在 /bin 和 /usr/bin 中创建了一些符号链接)。

【讨论】:

    【解决方案2】:

    不得不重新审视这一点,因为我们无法弄清楚为什么我们会卡在节点 8 上,即使我们在 EB UI 中将其设置为节点 12。似乎如果您安装一个全局节点,它会覆盖版本设置。这不是安装全局节点,而是使用 Elastic Beanstalk 节点安装并将其添加到路径中。您必须在 yarn 安装脚本的开头再次添加 PATH,但这似乎是使用 yarn 侵入性最小的方式。

    content: |
      #!/usr/bin/env bash
      set -euxo pipefail
    
      EB_NODE_VERSION=$(/opt/elasticbeanstalk/bin/get-config optionsettings -n aws:elasticbeanstalk:container:nodejs -o NodeVersion)
      echo "EB node version: $(EB_NODE_VERSION)"
    
      # Make sure Node binaries can be found (required to run npm).
      # And this lets us invoke npm more simply too.
      export PATH=/opt/elasticbeanstalk/node-install/node-v$EB_NODE_VERSION-linux-x64/bin:$PATH
    
      if yarn -v; then
        echo 'Yarn already installed.'
      else
        echo 'Installing yarn...'
        npm install yarn -g
      fi
    

    【讨论】:

    • 我可以把这个文件放在哪里?它需要任何特殊的文件名吗?
    【解决方案3】:

    我想出的这种方式让您仍然可以通过 Elastic Beanstalks Dashboard 控制节点版本。

    感谢您提出这个问题!没有它就不可能得到这个解决方案:D

     "/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh":
            mode:    "000755"
            owner:   root
            group:   users
            content: |
               #!/usr/bin/env bash
               #
               # Prevent installing or rebuilding like Elastic Beanstalk tries to do by
               # default.
               #
               # Note that this *overwrites* Elastic Beanstalk's default 50npm.sh script
               # (https://gist.github.com/wearhere/de51bb799f5099cec0ed28b9d0eb3663).
        "/opt/elasticbeanstalk/hooks/configdeploy/pre/50npm.sh":
            mode:    "000755"
            owner:   root
            group:   users
            content: |
               #!/usr/bin/env bash
               #
               # Prevent installing or rebuilding like Elastic Beanstalk tries to do by
               # default.
               #
               # Note that this *overwrites* Elastic Beanstalk's default 50npm.sh script.
               # But their default script actually doesn't work at all, since the app
               # staging dir, where they try to run `npm install`, doesn't exist during
               # config deploys, so ebnode.py just aborts:
               # https://gist.github.com/wearhere/de51bb799f5099cec0ed28b9d0eb3663#file-ebnode-py-L140
        "/opt/elasticbeanstalk/hooks/appdeploy/pre/49yarn.sh" :
            mode:    "000775"
            owner:   root
            group:   users
            content: |
               tmp="$(mktemp || bail)";
               app="$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)";
               version="$(/opt/elasticbeanstalk/bin/get-config optionsettings -n aws:elasticbeanstalk:container:nodejs -o NodeVersion)";
               echo $version
               major="$(cut -d'.' -f1 <<<${version})"
               yum -y install python26 python26-libs
               wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo;
    
               wget "https://rpm.nodesource.com/pub_${major}.x/el/7/x86_64/nodejs-${version}-1nodesource.x86_64.rpm" -O "${tmp}";
               rpm -i --nosignature --force "${tmp}";
               rm -f "${tmp}";
    
               yum -y install yarn;
    
               cd "${app}";
               yarn --production;
    

    【讨论】:

      【解决方案4】:

      我想出了一个办法,但是有点笨拙。

      1. 创建一个.ebextensions/yarn.config 文件。 (名称不必是“纱线”。)
      2. 将此内容放入文件中:

        files:
        # Runs right before `npm install` in '.../50npm.sh'
        "/opt/elasticbeanstalk/hooks/appdeploy/pre/49yarn.sh" :
            mode: "000775"
            owner: root
            group: users
            content: |
                #!/bin/bash
        
                app="$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)";
        
                # install node
                curl --silent --location https://rpm.nodesource.com/setup_8.x | bash -;
        
                # install yarn
                curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo;
                yum -y install yarn;
        
                # install node_modules with yarn
                cd "${app}";
                yarn --production;
        

      这个 ebextension 创建了一个文件,它做了 3 件事:

      1. 安装节点。
      2. 安装纱线。
      3. 使用 yarn 安装 node_modules。

      为了使 Elastic Beanstalk 在运行 npm install 之前运行 yarn install,在 /opt/elasticbeanstalk/hooks/appdeploy/pre 下创建文件。这会将文件转换为预部署挂钩,这意味着 Elastic Beanstalk 将在部署的第一阶段运行它。默认情况下,此目录中还有一个名为50npm.sh 的文件,它运行npm install。由于 Elastic Beanstalk 按字母顺序运行此目录中的文件,49yarn.sh(我们的文件)将在50npm.sh(默认文件)之前运行,导致yarn install 在npm install 之前运行。

      一个潜在的问题是,在 Elastic Beanstalk UI(Configuration > Software Configuration 下)中设置的环境变量在部署阶段的这一点上不可用。如果你有一个用于安装私有 npm 模块的 npm auth 令牌,这是一个大问题。

      另一个潜在问题是这会手动安装节点,因此您在 Elastic Beanstalk UI 中指定的“节点版本”(在Configuration > Software Configuration 下)不会影响您的应用程序使用的节点版本;您需要在此 ebextension 中指定它。 Elastic Beanstalk 的50npm.sh 既安装节点又运行npm install。由于我们必须在该文件运行之前运行yarn install,因此我们还必须手动安装节点。然后,当 Elastic Beanstalk 去安装节点时,它会检测到节点已经安装但不验证它是否是正确的版本,因此它会跳过节点安装。

      供参考,yarn安装说明来自这里:https://yarnpkg.com/docs/install#linux-tab

      【讨论】:

      • "/tmp/deployment/application" 只是一个占位符,还是 beantalk 部署中涉及的实际目录?
      • 是的 /tmp/deployment/application 是 beanstalk 放置项目代码的地方。 Beanstalk 删除该文件夹并在每次部署期间重新创建它。 Amazon 可能选择将其放在 /tmp 中,因为按照 UNIX 惯例,只要系统关闭,/tmp 就会被删除。
      • 这就像一个魅力!我唯一的建议是使用/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir 来获取包含项目的临时文件夹,而不是硬编码/tmp/deployment/application。
      • 我更新了帖子以使用该命令动态获取应用程序目录。
      • 补充以上内容,应该指出的是,这将覆盖 EB 的 NodeVersion 配置,因为您正在安装 Node 6。我只是花了很长时间试图弄清楚它为什么不使用 Node 8,才发现是curl那一行!
      【解决方案5】:

      我按照https://yarnpkg.com/lang/en/docs/install/ 上的说明执行此操作

      commands:
        01_install_yarn:
          command: "sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo && curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash - && sudo yum install yarn -y"
      

      【讨论】:

      • 你把这个添加到哪个文件中?
      猜你喜欢
      • 2013-12-31
      • 2012-09-30
      • 2021-07-18
      • 2020-11-01
      • 2016-06-07
      • 2016-09-14
      • 2018-04-14
      • 2016-01-01
      • 2017-12-04
      相关资源
      最近更新 更多