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

Posted

技术标签:

【中文标题】如何为在 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? 【发布时间】:2021-11-09 07:30:05 【问题描述】:

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

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

01_django.config:

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

问题是,django-pipeline 使用需要 Node 的压缩器库。

我已将两个库(cssminterser我的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

返回同样的错误:

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

这是错误来源的cssmin 文件的样子:

#!/bin/sh
basedir=$(dirname "$(echo "$0" | 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

我已经尝试过预构建挂钩

#!/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

那个时候节点好像不在系统路径上?

【问题讨论】:

【参考方案1】:

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

更新:

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

【讨论】:

我没有提到它,但我已经尝试过以及预部署挂钩 .sh 文件。我在问题的“编辑 #1”下提供了更多上下文。 @Jarad 您是否检查了 EB 日志,或者您是否尝试过 ssh 进入 EB 实例并自己修改节点安装?只是为了检查它是否有效?因为这些步骤应该有效。 是的,我在 SSH 上花了很多时间。我同意这些步骤也应该有效。我让它工作的唯一方法是,如果我 SSH 并在实例上手动安装,然后部署。我想避免将来出于自动缩放的原因手动进行任何操作。我会坚持下去的。 @Jarad 我提供的commands 是否安装node?如果你ssh,你能验证它是否安装了吗? 感谢替代节点安装方法!你完全正确;它一直安装在 /root 位置并且不在路径中,因此 Elastic Beanstalk 没有看到它。

以上是关于如何为在 64 位 Amazon Linux 2 上运行的 Elastic Beanstalk Python 3.7 项目安装节点包?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS EB Amazon Linux 2 平台上为 cron.d 添加环境属性引用

如何为新的 Docker Amazon Linux 2 平台将 Dockerrun.json v2 转换为 Dockerrun.json v3?

在 64 位 Amazon Linux 2/3.2.2 和 Dockerrun.aws.json v3 上运行 Docker 的 Elastic Beanstalk

如何为64位python 3安装64位vlc库?

我们如何为 64 位操作系统设置 oledb 提供程序

有关如何为一个 amazon lightsail 实例配置多个/2 域的任何文档