使用nvm和pm2运行旧版node.js应用程序时出错

时间:2018-01-05 03:57:31

标签: node.js nginx pm2 nvm

我的问题

我有一个旧的 nodejs应用程序(在v0.8.18下运行!),我希望由于历史原因继续运行。我可以从命令行(即$ node app)正常运行它,但我不能通过pm2(即$ pm2 start app)运行它。

这是我的设置:

  • Ubuntu 16.04
  • 使用nvm
    • 已安装用于运行旧版应用的节点{{1}
    • 节点v0.8.18最新稳定版本,全局安装了pm2
  • App通过nginx(大致跟these instructions
  • 反向代理
  • 我在创建的following this thread应用的根文件夹中有一个配置文件v9.3.0,如下所示:
pm2.json
  • 从pm2开始:
[{
  "name": "my-old-app",
  "exec_interpreter": "node@0.8.18",
  "script": "app.js",
  "error": "error.log"
}]

的产率:

$ NVM_DIR=/home/myusername/.nvm/ pm2 start pm2.json

当我开始尝试以这种方式启动应用时,这是运行$ NVM_DIR=/home/myusername/.nvm/ pm2 start pm2.json [PM2][WARN] Applications my-old-app not running, starting... [PM2] Setting Node to v0.8.18 (path=/home/myusername/.nvm/v0.8.18/bin/node) [PM2] App [my-old-app] launched (1 instances) ┌─────────────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬────────────┬──────────┐ │ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │ ├─────────────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼────────────┼──────────┤ │ my-old-app │ 0 │ fork │ 5879 │ online │ 0 │ 0s │ 0% │ 7.9 MB │ myusername │ disabled │ └─────────────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴────────────┴──────────┘ Use `pm2 show <id|name>` to get more details about an app

的结果
pm2 show my-old-app

此外, Describing process with id 0 - name my-old-app ┌───────────────────┬──────────────────────────────────────────────────┐ │ status │ errored │ │ name │ my-old-app │ │ restarts │ 15 │ │ uptime │ 0 │ │ script path │ /home/myusername/my-old-app/app.js │ │ script args │ N/A │ │ error log path │ /home/myusername/my-old-app/error-0.log │ │ out log path │ /home/myusername/.pm2/logs/my-old-app-out-0.log │ │ pid path │ /home/myusername/.pm2/pids/my-old-app-0.pid │ │ interpreter │ /home/myusername/.nvm/v0.8.18/bin/node │ │ interpreter args │ N/A │ │ script id │ 0 │ │ exec cwd │ /home/myusername/my-old-app/ │ │ exec mode │ fork_mode │ │ node.js version │ N/A │ │ watch & reload │ ✘ │ │ unstable restarts │ 0 │ │ created at │ N/A │ └───────────────────┴──────────────────────────────────────────────────┘ 中反复出现的错误是:

error-0.log
  

我不知道为什么这不起作用。

有什么用?

如果我只是从命令行正常运行应用程序,它会按预期完美地运行,即

domain.js:66
    throw er;
          ^
TypeError: Object #<Object> has no method 'unref'
    at Object.PMX.init (/home/myusername/.nvm/versions/node/v9.3.0/lib/node_modules/pm2/node_modules/pmx/lib/pmx.js:81:8)
    at Object.<anonymous> (/home/myusername/.nvm/versions/node/v9.3.0/lib/node_modules/pm2/lib/ProcessContainerFork.js:8:18)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

它通过nginx进行反向代理,并通过https://old.example.com在浏览器中提供。仅供参考,我的nginx网站配置的内容:

$ nvm use 0.8.18
Now using node v0.8.18 (npm v1.2.2)
$ node app
   info  - socket.io started
Express server listening on port 37426

显然,我不能只使用此设置,因为如果进程因任何原因而中断,它将不会重新启动。有任何想法吗?我尝试使用节点server { listen 80; listen [::]:80; listen 443 ssl; ssl_certificate /etc/letsencrypt/live/old.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/old.example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; server_name old.example.com; if ($scheme != "https") { return 301 https://$host$request_uri; } # Pass requests for / to localhost:37426: location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_pass http://localhost:37426/; proxy_ssl_session_reuse off; proxy_set_header Host $http_host; proxy_cache_bypass $http_upgrade; proxy_redirect off; } } 运行应用程序,但代码太旧了。它也过于庞大,无法以更新的形式重新编写。

2 个答案:

答案 0 :(得分:0)

从错误日志中,您似乎正在尝试使用节点v9.3.0运行应用。

将您的命令修改为此类[未经测试]

NVM_DIR=/home/myusername/.nvm/ nvm use 0.8.18 && pm2 start pm2.json

答案 1 :(得分:0)

我明白了。 pm2 depends upon pmx,后者又使用setTimeout().unref() function。在while之前,unref()函数未添加到nodejs。由于我尝试使用节点v0.9.1运行我的应用,因此v0.8.18函数未定义,因此unref()错误消息。

尝试在较新的节点版本下运行我的应用程序总是失败,但最终我意识到它总是失败,因为相同的包:Object #<Object> has no method 'unref'。事实证明,这个软件包的原始作者使用了一个奇怪的,错误的,中间版本的bcryptbcrypt)。当我将其更新为更新的v0.7.5bcrypt)时,我能够使用节点v0.7.6运行整个应用,这反过来使v0.9.12安全使用pm2

摘要......

  1. 请勿尝试使用unref()尝试运行节点应用pm2
  2. 如果您这样做,您可能需要修改应用,以便可以使用节点<v0.9.1
  3. 运行该应用

    更新

    >=v0.9.1的其中一位维护者让我知道they don't officially support any versions of nodejs <v0.12 and soon they'll be dropping support for that as well