npm 自定义AWS ElasticBeanstalk NodeJS安装(使用yarn)

iyfamqjs  于 8个月前  发布在  Yarn
关注(0)|答案(6)|浏览(90)

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

ryevplcw

ryevplcw1#

我想到了一个办法,但它是一个小黑客。
1.创建.ebextensions/yarn.config文件。* (名称不一定是“yarn”)*
1.将此内容放入文件中:

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创建了一个文件,它做了三件事:
1.安装节点。
1.安装Yarn。
1.使用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 installnpm install之前运行。
一个潜在的问题是,Elastic Beanstalk UI中设置的环境变量(在Configuration> Software Configuration下)在部署阶段的这一点上不可用。这是一个大问题,如果你有一个npm auth token,你可以用来安装私有npm模块。
另一个潜在的问题是,这将手动安装节点,因此您在Elastic Beanstalk UI中指定的“Node version”(在Configuration> Software Configuration下)将不会影响您的应用程序使用的节点版本;你需要在这个ebextension中指定它。Elastic Beanstalk的50npm.sh既安装node又运行npm install。由于我们必须在该文件运行之前运行yarn install,因此我们还必须手动安装node。然后,当Elastic Beanstalk去安装节点时,它检测到节点已经安装,但没有验证它是正确的版本,所以它跳过了节点安装。
作为参考,Yarn安装说明来自这里:https://yarnpkg.com/docs/install#linux-tab

a0x5cqrl

a0x5cqrl2#

我按照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"
xesrikrc

xesrikrc3#

我提出的这种方法仍然可以让您通过Elastic Beanstalks Jmeter 板控制节点版本。
感谢您的提问!如果没有它,就不可能得到这个解决方案: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;
byqmnocz

byqmnocz4#

我们不得不重新审视这个问题,因为我们无法弄清楚为什么我们被困在节点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
xmq68pz9

xmq68pz95#

阻止EB运行npm install的一个简单方法是在prebuild钩子中创建一个空的node_modules文件夹:
编辑your_project/.platform/hooks/prebuild/prevent-npm.sh

#!/bin/bash
# EB build scripts will not install using npm if node_modules folder exists
mkdir node_modules

这样,EB仍然会安装Node.js,所以你不必自己安装。但当node_modules存在时,它将跳过npm install
然后在predeploy钩子中,您可以运行yarn。如果你运行的是Node.js 16或更高版本,你可以使用corepack yarn,它会正常工作(你不必从yum、npm或其他任何东西安装yarn)。
编辑your_project/.platform/hooks/predeploy/yarn.sh

#!/bin/bash
corepack yarn

**更新:**自Amazon Linux 2023起,corepack不再包含,需要显式安装:

编辑your_project/.platform/hooks/prebuild/corepack.sh

#!/bin/bash
npm i -g corepack

请确保在项目中的confighooks下也创建了符号链接,否则在更改配置时会无法构建(例如:更新环境值):

mkdir -p .platform/confighooks/{prebuild,predeploy}
ln -s ../../hooks/predeploy/yarn.sh .platform/confighooks/predeploy/yarn.sh
ln -s ../../hooks/prebuild/prevent-npm.sh .platform/confighooks/prebuild/prevent-npm.sh
ln -s ../../hooks/prebuild/corepack.sh .platform/confighooks/prebuild/corepack.sh
2ul0zpep

2ul0zpep6#

由于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=逻辑放在脚本中,并在每个yarn命令之前调用它,以便在扩展中有干净的command:指令。
另外,请注意,如果您使用yum包管理器安装yarn,您完全破坏了Beanstalk提供的NodeJS版本管理(因为它背后运行的黑魔法在/bin/usr/bin中创建了一些符号链接)。

相关问题