I have an old nodejs app (runs under v0.8.18
!) that I'd like to keep running for historical reasons. I can run it normally from the command line (ie $ node app
), but I can't run it via pm2 (ie $ pm2 start app
).
nvm
v0.8.18
installed for running the legacy app v9.3.0
latest stable version with pm2
installed globally pm2.json
in the root folder of the app created following this thread that looks as follows: [{
"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
yields:
$ 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
When I start try to start the app this way, here is the result of running 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 │
└───────────────────┴──────────────────────────────────────────────────┘
Furthermore, the error that shows up repeatedly in error-0.log
is:
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)
I don't know why this doesn't work.
If I just run the app normally from the command line, it works perfectly as expected, ie
$ 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
It gets reverse proxied through nginx and is available in a browser via https://old.example.com . FYI, the contents of my nginx site config:
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;
}
}
Clearly, I can't just use this setup because if the process is interrupted for any reason, it won't get restarted. Any ideas? I tried just running the app with node v9.3.0
but the code is too old. It's also too extensive to just re-write in more up-to-date form.
From the error log, it seems you are trying to run the app using node v9.3.0
.
modify your command into something like this [ not tested ]
NVM_DIR=/home/myusername/.nvm/ nvm use 0.8.18 && pm2 start pm2.json
I figured it out. pm2
depends upon pmx
, which in turn uses the setTimeout().unref()
function . The unref()
function was not added to nodejs until v0.9.1
. Since I was trying to run my app with node v0.8.18
, the unref()
function was undefined hence the Object #<Object> has no method 'unref'
error message.
Trying to run my app under newer node versions always failed, but eventually I realized it was always failing because of the same package: bcrypt
. It turns out the original authors of this package had used a weird, buggy, in-between version of bcrypt
( v0.7.5
). When I switched it up to a slightly newer bcrypt
( v0.7.6
), I was able to run the entire app with node v0.9.12
, which in turn, made it safe for pm2
to use unref()
.
pm2
to try to run node apps <v0.9.1
, or >=v0.9.1
One of the maintainers of pm2
let me know that they don't officially support any versions of nodejs <v0.12
and soon they'll be dropping support for that as well .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.