如何告诉 pm2 在部署时使用特定节点版本

How To Tell pm2 to Use Specific Node Version On Deploy

编辑——尝试使用旧版本的节点 (8.1.0) 在我的机器上安装 puppeteer 后,它会抛出相同的错误。因此,问题一定是在连接到机器时,它没有加载正确的节点版本。那么问题是,如何使用正确的 node.js 版本 运行 pm2 post-部署挂钩?

我在尝试使用 pm2 deploy 部署我的网络抓取应用程序时遇到了一个非常奇怪的错误。错误出现在 pm2 部署过程的 post-install 挂钩期间,也就是 yarn 将各种软件包安装到我的远程计算机 (Ubuntu 18.04) 时。

错误如下所示:

....The rest of the yarn installation...

[4/4] Building fresh packages...    
error /home/harrison/gql3.0_processors/source/node_modules/puppeteer: Command failed.
Exit code: 1
Command: node install.js
Arguments:
Directory: /home/harrison/gql3.0_processors/source/node_modules/puppeteer
Output:
/home/harrison/gql3.0_processors/source/node_modules/puppeteer/install.js:175
            } catch {
                    ^

SyntaxError: Unexpected token {
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)    
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:188:16)
    at bootstrap_node.js:609:3
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

  post-deploy hook failed

Deploy failed

这来自我的 node_modules 文件夹的 puppeteer 目录中的 install.js 文件,这是我在我的项目中使用的依赖项。

我倾向于认为这是由于我远程安装应用程序时我的节点版本出现了某种错误?谁能提供一些指导?

我的 pm2 部署文件如下(有关更多信息,请转到此处:https://pm2.keymetrics.io/docs/usage/application-declaration/

require("dotenv").config({ path: `./envs/.env.production` });
const path = require("path");

let hosts = process.env.HOSTS.split(",");
let hostsBashArgs = process.env.HOSTS.replace(/,/g, " "); // Pass as args to bash script

module.exports = {
  apps: [
    {
      name: process.env.APP_NAME,
      args: ["--color"],
      interpreter: process.env.NODE_PATH, // Installation of node on my remote machine, it's ––> `/home/harrison/.nvm/versions/node/v13.7.0/bin/`
      cwd: path.resolve(process.env.PROJECT_PATH, "current"), // Where post-deploy runs
      script: "dist/index.js", // Webpacked server file
      instances: process.env.INSTANCES || 0,
      exec_mode: "cluster",
      env: {
        ...process.env,
      },
    },
  ],
  deploy: {
    production: {
      user: "harrison",
      host: hosts,
      key: "~/.ssh/id_rsa2",
      ref: "origin/master",
      repo: process.env.GIT_REPO,
      path: process.env.PROJECT_PATH,
      "pre-deploy-local": `./deployEnvs.sh ${process.env.PROJECT_PATH} ${hostsBashArgs}`,
      //// THIS IS THE STEP WHICH FAILS 
      "post-deploy": `yarn install --ignore-engines && \
       yarn prod:build && \
       yarn prod:serve`,
    },
  },
};

出于某种原因,pm2 post-deploy 脚本没有加载到我的 .zshrc 文件中,因此它尝试使用的 Node.js 版本是不正确。我能够在 post-安装阶段看到这一点,运行 printenv 命令(显示 $PATH 变量不包括我的 nvm 版本).

因此,解决方案是在 post-deploy 脚本期间专门获取 .zshrc 文件(或 .bashrc 文件供使用 bash 的用户使用),如下所示:

  ... The rest of the ecosystem.config.js file ...
  deploy: {
  production: {
    user: "harrison",
    host: hosts,
    key: "~/.ssh/id_rsa",
    ref: "origin/master",
    repo: process.env.GIT_REPO,
    path: process.env.PROJECT_PATH,
    /// Source the user's .zshrc file first!!
    "post-deploy": `source ~/.zshrc && \ 
     yarn install --ignore-engines && \
     yarn prod:build && \
     yarn prod:serve`
    }
}

这是必要的,因为我的 .zshrc 文件是在 nvm 环境中加载的文件(并设置了我对更高版本节点的加载)。该节点版本是 运行 安装脚本时 yarn 所依赖的,这就是过时版本失败的原因。

要使用您的节点版本更新创建的 pm2 应用程序,请按照以下步骤操作:

  1. nvm 使用(版本)。 示例 nvm 使用 14.17.0.
  2. NODE_ENV=production pm2 restart nameOfYourApp --update-env