如何在 64 位 Amazon Linux 2 上为 Elastic Beanstalk Python 3.7 项目 运行 安装节点包?

How to install Node Packages for an Elastic Beanstalk Python 3.7 Project Running on 64bit Amazon Linux 2?

我正在使用名为 django-pipeline 的 Django 包来压缩 js 和 css 文件。

当我部署我的项目时,我 运行 Django 的 collectstatic 命令,来自 .ebextensions 文件夹:

01_django.config:

container_commands:
    ...
    07_collectstatic:
        command: "source /var/app/venv/*/bin/activate && python3 manage.py collectstatic --noinput"

问题是,django-pipeline 使用需要 Node.

的压缩器库

我复制了两个库(cssminterserfrom 我的 node_modules 本地目录 我的 static 目录。

static
|_vendor
|___|.bin
|_____|cssmin
|_____|cssmin.cmd
|_____|terser
|_____|terser.cmd
|___|cssmin
|_____|...
|___|terser
|_____|...

其次,我在管道上设置了以下设置来告诉管道二进制文件存在的位置:

PIPELINE_CONFIG.update({
    'CSSMIN_BINARY': os.path.join(BASE_DIR, "static", "vendor", ".bin", "cssmin"),
    'TERSER_BINARY': os.path.join(BASE_DIR, "static", "vendor", ".bin", "terser"),
})

错误

2021-09-14 05:00:58,513 P4080 [INFO] ============================================================
2021-09-14 05:00:58,513 P4080 [INFO] Command 07_collectstatic
2021-09-14 05:00:59,502 P4080 [INFO] -----------------------Command Output-----------------------
2021-09-14 05:00:59,503 P4080 [INFO]    Traceback (most recent call last):
2021-09-14 05:00:59,503 P4080 [INFO]      File "manage.py", line 21, in <module>
2021-09-14 05:00:59,503 P4080 [INFO]        main()
2021-09-14 05:00:59,503 P4080 [INFO]      File "manage.py", line 17, in main
2021-09-14 05:00:59,503 P4080 [INFO]        execute_from_command_line(sys.argv)
2021-09-14 05:00:59,503 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
2021-09-14 05:00:59,503 P4080 [INFO]        utility.execute()
2021-09-14 05:00:59,503 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/core/management/__init__.py", line 413, in execute
2021-09-14 05:00:59,503 P4080 [INFO]        self.fetch_command(subcommand).run_from_argv(self.argv)
2021-09-14 05:00:59,503 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/core/management/base.py", line 354, in run_from_argv
2021-09-14 05:00:59,503 P4080 [INFO]        self.execute(*args, **cmd_options)
2021-09-14 05:00:59,503 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/core/management/base.py", line 398, in execute
2021-09-14 05:00:59,503 P4080 [INFO]        output = self.handle(*args, **options)
2021-09-14 05:00:59,503 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 187, in handle
2021-09-14 05:00:59,503 P4080 [INFO]        collected = self.collect()
2021-09-14 05:00:59,503 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 128, in collect
2021-09-14 05:00:59,503 P4080 [INFO]        for original_path, processed_path, processed in processor:
2021-09-14 05:00:59,504 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/pipeline/storage.py", line 30, in post_process
2021-09-14 05:00:59,504 P4080 [INFO]        packager.pack_stylesheets(package)
2021-09-14 05:00:59,504 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/pipeline/packager.py", line 98, in pack_stylesheets
2021-09-14 05:00:59,504 P4080 [INFO]        variant=package.variant, **kwargs)
2021-09-14 05:00:59,504 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/pipeline/packager.py", line 116, in pack
2021-09-14 05:00:59,504 P4080 [INFO]        content = compress(paths, **kwargs)
2021-09-14 05:00:59,504 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/pipeline/compressors/__init__.py", line 75, in compress_css
2021-09-14 05:00:59,504 P4080 [INFO]        css = getattr(compressor(verbose=self.verbose), 'compress_css')(css)
2021-09-14 05:00:59,504 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/pipeline/compressors/cssmin.py", line 8, in compress_css
2021-09-14 05:00:59,504 P4080 [INFO]        return self.execute_command(command, css)
2021-09-14 05:00:59,504 P4080 [INFO]      File "/var/app/venv/staging-LQM1lest/lib/python3.7/site-packages/pipeline/compressors/__init__.py", line 250, in execute_command
2021-09-14 05:00:59,504 P4080 [INFO]        raise CompressorError(stderr)
2021-09-14 05:00:59,504 P4080 [INFO]    pipeline.exceptions.CompressorError: b'/var/app/staging/static/vendor/.bin/cssmin: line 12: node: command not found\n'
2021-09-14 05:00:59,504 P4080 [INFO] ------------------------------------------------------------
2021-09-14 05:00:59,504 P4080 [ERROR] Exited with error code 1

我的问题

如何在 Python 3.7 Elastic Beanstalk 环境中安装节点,以便这个 collectstatic 命令可以工作?

编辑 #1

我试过:

commands:
  05_install node:
    command: |
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
      . ~/.nvm/nvm.sh
      nvm install node

它returns同样的错误:

pipeline.exceptions.CompressorError: b'/var/app/staging/static/vendor/.bin/cssmin: line 12: node: command not found\n'

出现错误的 cssmin 文件如下所示:

#!/bin/sh
basedir=$(dirname "$(echo "[=19=]" | sed -e 's,\,/,g')")

case `uname` in
    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
  "$basedir/node"  "$basedir/../cssmin/bin/cssmin" "$@"
  ret=$?
else 
  node  "$basedir/../cssmin/bin/cssmin" "$@" <----------- line 12
  ret=$?
fi
exit $ret

我已经尝试了 prebuild hooks:

#!/bin/bash

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
source /root/.nvm/nvm.sh
nvm install node
export NVM_DIR="/root/.nvm"
node -e "console.log('Running Node.js ' + process.version)"

来自 Elastic Beanstalk 的 eb-hooks.log 中预构建挂钩的结果:

2021/09/14 15:13:59.896274 [INFO] => nvm is already installed in /root/.nvm, trying to update the script

=> nvm source string already in /root/.bashrc
=> bash_completion source string already in /root/.bashrc
=> You currently have modules installed globally with `npm`. These will no
=> longer be linked to the active version of Node when you install a new node
=> with `nvm`; and they may (depending on how you construct your `$PATH`)
=> override the binaries of modules installed with `nvm`:

/root/.nvm/versions/node/v16.9.1/lib
+-- corepack@0.9.0
=> If you wish to uninstall them at a later point (or re-install them under your
=> `nvm` Nodes), you can remove them from the system Node as follows:

     $ nvm use system
     $ npm uninstall -g a_module

=> Close and reopen your terminal to start using nvm or run the following to use it now:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
Now using node v16.9.1 (npm v7.21.1)
Running Node.js v16.9.1

上面的输出显示节点已安装,但我的 collectstatic 容器命令仍然失败,无法找到节点。

失败后,我可以SSH进入实例,看到定位nvm的环境变量存在:

declare -x NVM_BIN="/root/.nvm/versions/node/v16.9.1/bin"
declare -x NVM_CD_FLAGS=""
declare -x NVM_DIR="/root/.nvm"

当我在 container_commands:

中 运行 which node 时,我得到了一个有趣的输出
2021-09-14 16:40:46,512 P8087 [INFO]    which: no node in (/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin)
2021-09-14 16:40:46,512 P8087 [INFO] ------------------------------------------------------------
2021-09-14 16:40:46,512 P8087 [ERROR] Exited with error code 1

那个时候节点似乎不在系统路径上?

您可以使用 commands 并执行以下操作:

更新:

commands:
    05_install node:
        command: |
          curl -sL https://rpm.nodesource.com/setup_16.x | sudo bash -
          yum install -y nodejs